更新,工序计划
This commit is contained in:
parent
ac596588b5
commit
5e091843b0
8
.gitignore
vendored
8
.gitignore
vendored
@ -14,3 +14,11 @@ maven-wrapper.properties
|
||||
**/logs/
|
||||
|
||||
/logs/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
*.iml
|
||||
.vscode/
|
||||
|
||||
# 本地文档/工具(默认不进仓库;需要单独提交时再强制 add)
|
||||
docs/
|
||||
|
||||
5
.idea/.gitignore
vendored
5
.idea/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Annotation profile for RuoYi-Vue-Plus" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<processorPath useClasspath="false">
|
||||
<entry name="$MAVEN_REPOSITORY$/com/github/therapi/therapi-runtime-javadoc-scribe/0.15.0/therapi-runtime-javadoc-scribe-0.15.0.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/com/github/therapi/therapi-runtime-javadoc/0.15.0/therapi-runtime-javadoc-0.15.0.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-configuration-processor/2.7.11/spring-boot-configuration-processor-2.7.11.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/com/github/therapi/therapi-runtime-javadoc-scribe/0.15.0/therapi-runtime-javadoc-scribe-0.15.0.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/com/github/therapi/therapi-runtime-javadoc/0.15.0/therapi-runtime-javadoc-0.15.0.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" />
|
||||
<entry name="$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-configuration-processor/2.7.11/spring-boot-configuration-processor-2.7.11.jar" />
|
||||
</processorPath>
|
||||
<module name="ruoyi-framework" />
|
||||
<module name="ruoyi-oss" />
|
||||
<module name="ruoyi-demo" />
|
||||
<module name="ruoyi-system" />
|
||||
<module name="ruoyi-job" />
|
||||
<module name="ruoyi-monitor-admin" />
|
||||
<module name="ruoyi-sms" />
|
||||
<module name="ruoyi-common" />
|
||||
<module name="ruoyi-generator" />
|
||||
<module name="ruoyi-xxl-job-admin" />
|
||||
<module name="ruoyi-admin" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-admin/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-admin/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-common/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-common/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-demo/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-demo/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/ruoyi-monitor-admin/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/ruoyi-monitor-admin/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/ruoyi-xxl-job-admin/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-extend/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-framework/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-framework/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-generator/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-generator/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-job/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-job/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-oss/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-oss/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-sms/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-sms/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-system/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/ruoyi-system/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="public" />
|
||||
<option name="name" value="aliyun nexus" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="enabledProfiles">
|
||||
<list>
|
||||
<option value="dev" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK" />
|
||||
</project>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
File diff suppressed because it is too large
Load Diff
374939
logs/ruoyi-xxl-job-admin.log
374939
logs/ruoyi-xxl-job-admin.log
File diff suppressed because it is too large
Load Diff
5294
logs/sys-console.log
5294
logs/sys-console.log
File diff suppressed because it is too large
Load Diff
4113
logs/sys-error.log
4113
logs/sys-error.log
File diff suppressed because it is too large
Load Diff
@ -1,444 +0,0 @@
|
||||
2026-05-18 08:34:03 [connection-pool-2-1] INFO c.d.o.a.s.n.w.WebsocketTransportConnector - [DingTalk] start websocket connection, uri=wss://wss-open-connection-union.dingtalk.com:443/connect
|
||||
2026-05-18 08:34:03 [connection-pool-2-1] INFO c.d.o.a.s.n.core.DefaultSessionPool - [DingTalk] connection is established, connectionId=451fc31e-5251-11f1-8397-a2985f78c079
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"970975bfc38c1a9acc74c573fec3aa02b216b77f","msg_signature":"970975bfc38c1a9acc74c573fec3aa02b216b77f","timestamp":"1779065001340","nonce":"5eVXd79A","encrypt":"NUUFVmiLTgmVB0EndP4sbmCVxfw9VsVqUWye/GTJHrVVYy6Y1lK8xytUwAug3WlujTvCNIGn4VmXdxMxA5ibBboZqZsqtWonuZn3LAGoDCzlldLwEw1jNbE/gLxH47lNWMIWfuTpxGr3fUCyga5CDZ6o/F3n1Vq2JhuA7tPt4ONqAYFfWaYWewNuHQFkXu02/6jOFGeVSKb+GUnORMjyPZFqbV/TTaKa/EzH0WRnqUiJrF8sxLtdjMF9UMC5QYNqk+1Nw0sjSjWxnJvyjaBgwPhNhXsQ4Y2CGupMcNw0h3QoQCxDcPDowLqF/zZv3PFKQMr0cxd5e1aJcl63pjzs6MlOIqg8patj3fLrtjD7+DfLSOpS3QIWR8v/pedaGoOXmj1AMJkN/yO2QvYADbzXk6ukz2d4jFEBy8OJNgmitI17mq7M+a7u0SDZoWWMV1Dxv51jH3YB1t4RoVmI1em4F3qjiISI7fzfkxx6l8KX3dunE7X63A51st5kl2FajKmIm8hSXP/qO85h/VyYLgeEqxTvzrbp6mCEhZnV8tfnmgq+gBfok7pDXe0Jfu39y5p6JFhUosMfDQMjE3rDXBfXXtU+eFqc0YonJ7+AsqNXAPmWyMypYBOfM3NvztLQd+gs12GcEUTz+hAh+pFx0s3QGsKbmqR2hk1NJLeMvXZt5NuPqwFCOQx98E944dLruJaxrifXgytWLcmpf4H6n0PKMxsbCuCJWVYjKT/b6FeD5SdZ3Qs+URbTwtBJeopbgubZUL4x61dG6dEEMC2grcNdZPoYSkO2JEz1tmOlSuCyOmYQqiAH9TjtBYI618py5EJ2Qo1mztMHrj8v3t7icCggQ9THoOyhZVgM9toEIkJS4bCEmw1Gd1sMhO6ofkfRzVTIdAn2cx1nstB5tZk7va8IEazfuHkYFuCbIL0GkC6gsXow0WtVqfGaU2QWI62g6m3IdmLRTkXqvIPzRzyYI4xmVy0zh7jDuOhSlbmBgsryL+I80l6df+pvf0UIApULkmGdlu/eNsyMK+UmFQaAKt0MX+m84OA3fKQkbldOslTmVE4="}
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"2c9565538e3b46b0b4a237002ead56cf","finishTime":1779065000000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1778925260000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101156217321}
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:43:24 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065004374, msg_signature=42b8de361debef89d9e3f9c1310c4e04879111c4, encrypt=gUj5T88XBoYpMP16dzERFNG51JJ9Cqcl62iy3AUxr+nDx/5f3mLxGazBzp/M8tIdYRnCAUAtlKEvTlIRQRq4Pw==, nonce=7ldI5OO6FjWCDipG}
|
||||
2026-05-18 08:43:32 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"0a01e86c240e730fa0a807fcd280e4af58c21f2d","msg_signature":"0a01e86c240e730fa0a807fcd280e4af58c21f2d","timestamp":"1779065001503","nonce":"WD1WK2R7","encrypt":"Tu5FRnEDir4G3rKDZqB+CwBtFayooqRyv+X4/8RYUXuhLlLf4ZuZU2XDloKHEJd5bcMl59oPU6q3bQiuKQO4aZmmn85zju3lcLsBYn481tjIdrIFj0RLV5ra52HLfd7IJGdnFHlA12G8V6GnW5Lce0skcbar4GDK+X1lzMbD7iKIwCjkUqMZgMNAE7xRQBS5nyu6WZXdnD7AZx7SlxcFSf0dSDMt5yZj0v9382hVHpoQk2jq5UY+cAXPKmjzE6MScDZR65xoKiPq6e/tTPU3W+Sd4Q7i5ddAfQYZrvE7rOCEkXckUYrVGDPxYELdh3SGKj60mfNE/n/A8HNtHKyvsu4Y8beHyNzwoNUUxNvW5xDwZ2s7ujbTil+UWY4YNXBtHwao9F2Hm6iIo8rSIPt7LMXLSLgR0Xjq6h0tBOzxOVnGc96ItVpjIvNPyjf7/sM3xyLNiEhpU6CfuWo+XlraQbbh/hDBaV8LeQjtEGaYEFXI4/Y9IW3V6KReQAJp1wm+hKFSfltN7FtBggo8Zf2Aarak83gWZrCwTQYBPjI5IstGDgjS4XpeLDu6pVWXKvUng1lJP54FqoVe2cqKUl1Qz7uMt+fvyZQdQscalTXQTFdId1VGMOHPGnatxrsLhqCjgmNRivZNJtGp7fJ6dxllc0p3bHOF7Drov8OMsNbK+wXbg3bf6dTPRi+lVObeJvhTVvBKk/bIe1qaMSTLGKTcFsMzzkL5arspAgs6Rjly0rknzauKvzVBLQcuYAoeuiniH6cFZG5V5O3FMe+hZRoK5brFnobiSqnMLcRURhHqI+uKgeuf8HqQ8rVm2bUYL7ZyTIom2gFIsAQI+hsAD2sl37fJkf1ROis7p06eWPjtyqKmZG+gRM+FToqTcOe45BCw/YsT2ZiLwADX0uYpScME5LE8Zle9RPyTrH5Mja+eHhnmEpMtd5pZXQG/CbxdS6yY3XCNftpfVZuLRiDPcadlO3X59UlYkb5vh0QJ9mlsr8KL+2Gk4Vam1QgijODWTfnj"}
|
||||
2026-05-18 08:43:32 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"964fc204bc6b4e5dbe5755eaff059ac9","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"研发技术人员确认提交方案","actualActionerId":"01190846452221394385","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779065001000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"01190846452221394385","taskId":101208140285}
|
||||
2026-05-18 08:43:32 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:43:32 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:43:32 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065012881, msg_signature=ab6aceaea6c6cc4e644fb72a91320cf7130b3711, encrypt=9Tr0a9j3S9w4F7gYre7ZtcRU5AQJCw6tu3eNoC0q8/jPLiPdYItqrmvyf2oKZpSXYnEchp3G1AzUdbLhZAHSAA==, nonce=7RSNMTEXkxiTN62l}
|
||||
2026-05-18 08:43:39 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"bc8af64e15d2ef492a71df3a4a6078212a08a7d7","msg_signature":"bc8af64e15d2ef492a71df3a4a6078212a08a7d7","timestamp":"1779065014134","nonce":"XY2KoIR0","encrypt":"cNPeb19i9oVYsWDsZnsgrOBeHx7okf4Yy/QbVFm/Cf5ux3pFjko7ddE/c5tfjSF+7zgQjwQPnc/vkFBPuI34Dc9NQtB/4OAgqie4v9r72TgzSbffaFi0EK4AIlRXgtVmuaYQvJx1ur6v7m7Y07BMqsc+Sb2FyCZhKxipQ8rAmFGEqbDJre9q8fq0AQzKq5LfytGAZ5tg0TFxHQCUVC3vKlkJoinXr5LDaN/zWwlidQcuMwSHosBbt9rEKHWY6OY1miUoVeUD57CcgXRPULt+OwZnmqcvV3+SwLSYpoFpyITcYpDdccVtrySfDJRZaH+nb5x1dSb667Tb18Nve+YHYIprNV9FGijbNmqHl0tRUfEzjL5XrwuJAcmOgnMsV1Df5sMQ9Eiwdywfl6CbtRiCCAjny8aOJaVBcQe0xlCMx37e5jsJMHP80+8rQoPOExtIzSc9Lr+O5aZ38tsRhR6uOAiZJHq8mrr1GZRCZSnSz4uzY2h83/7+HmEbc2i5l1kF2GgjLY2mFLTktzJxm8/ISacokHrmdAS9YTIpNup2C88GcxxrpS0zSfqI/7qSUomSp2ZU2d6yZEymJvEGjTf8h9i3/y3xhoXlEj73E0V5M6JZn6qOr3c7gvs6oBX4Ynu8j0pO9OS9SfWAp7sl23kXbQB3Z/b0WzhKWFtQR+NMukCwPetC9CLtyTIwmRGQdXn46rPvUVEyXlZ8+R7Vl1FKJ6eY9h+5c0RJxMNUXnb/PrIE4K+tjdM5dwDqQ74FfwsFpJBt3GknYI93wmg/LbNxHYbaPKnvrGZBty1dDjdeRWByJSzrKwP9mVlSlBDTAIlVwvEyDVF25ewN0XKNWTx/W/MEiOaRdrWv+YuOpfOwS5zbuk2XUeokltp7xfPUCSJ336tANl1LtPwYFMc+YwmCSbMPaffgfCdMO3YnqLTjJ9SReMgjJkzvhQZCc7HPOErFApxEAaec0NAa8QzSWwemp2cOEBjHd/AxvNlaKfIgs+PgPXZPNy9vqQsh40jInQdv"}
|
||||
2026-05-18 08:43:39 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"964fc204bc6b4e5dbe5755eaff059ac9","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"研发技术人员确认提交方案","actualActionerId":"01190846452221394385","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779065001000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"01190846452221394385","taskId":101208140285}
|
||||
2026-05-18 08:43:39 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:43:39 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:43:39 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065019054, msg_signature=3951e5c0798ac44d531923db6ad4da2fbe1aa6ed, encrypt=cuXPbB+qCqLqKNssY8xetfQPEa4/vsFlfimLFBn586xmaD6bqjxsTHWvi1jVpd5h2CFChCtqgniMIqueHrPdhw==, nonce=AfUcHUQD1efB4klY}
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"151fc508f6363c520ea6b9192cb23a73b1fd1090","msg_signature":"151fc508f6363c520ea6b9192cb23a73b1fd1090","timestamp":"1779065014023","nonce":"PxO1oGmx","encrypt":"FBKoB/nJUq8QLTEfavJwaMysmUAa0+5HacszHptfORq/bsgYOM26mx3DwhaIGzh9ttEw2fVDl2eV5FqyvjBOc14/AxIDtduB79cDsrEAA1GpEiht116dgzGBrZLfJf37C9g6j+UBhaMa5+NjplZe/mW4MoY8+mNTJLocrFENh35Jo+a97kdkjPPww5eg0tU151jpzv2OnPystg6CELg2FwS2nkj2skdpOHH7F3iOfJF2QcJZJ4nmKYfUAnLziVyKmDkj/4gklm/qWvr5vA3SxzZPLNHg5a83msGtj+9AftgXjWrWiSJsBuTzgzgaUq9essoNUJZ1ru6q3FbzGQ6UNLEa/GDJXADGXqPynjGfi5maFtd2k/k5wGsyzGv/zgrttEFTuHMlY6xOkWcQLQgarbgEGyipaDzP5ma5QXWA0mi1aXhx2rBa1YY0YoMTKkff+2pLVas9U36kb8l0XVVt8iQBo/PU9v/N3Of9nSr0r7/T5BUm/ClNCHUxF5zFjqfrzkSo3G+A9As0Irff96mnznGPrrz4/QyKDwouXgtqPuwdAzBFMvSKdKGq9IpBOYA1pqSKqG0vGtwYKwZuD0A9YaW5mzc0gARyDcWqHeC7odlUscpm0WpbBtw3o+2LPL9Jlu/slhhqGtfKlcP3hwsj/gYNLRqEv5E621Mx22JhfAv8vktDSC4WlyhB/Bs8DWZFtYe/Pv3BrFL1KxJXqaV9p97jVfyNnf3hpoM8lDe5K/K92qQTuAdPmvMDne4NYQDMzvA4BUerVIIFeuGnC3Qm9A/G8XFLFrAbJDCAyshciUZIy1qQyU11qfE9gBy4/Z+C+YVhVev9dEYH6lgAytyN3ZCpCX7IGcPFj3jv8UhF8lQASZh7lBeHp72tvCtAJWVfgP8qU3IbVJBqOlFd3dKwZjsJMu9DuXez1PZXl6Y4/6kpN3JskVtBtxh95mIH0EVGJ4s55y/fmCHO2YhTg8EwLpJJyBDbxEWiZ9f/XFjps7QxQUDSaDWwJxjDKxI7WlU1uu3T68TSt723f44TvthuS2PDEBKSmMwkTMkgApJ6xag="}
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"2c9565538e3b46b0b4a237002ead56cf","finishTime":1779065000000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1778925260000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101156217321}
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:43:40 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065020651, msg_signature=99248a0fbe146e5b0c5c84a9c9f6f260cce255ad, encrypt=zhOdt6t9puYa1OqLY9Jk0yjeG4I4YarWoV8JBuzjg0P+EhHWKZAAgiEgrW+5LhRYcPxegD6Atg53dMqcexW0gw==, nonce=RlYjgrnfVKE3yBMF}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"53af8acaf7b0ecf05f2ac7cb31af738f95936f55","msg_signature":"53af8acaf7b0ecf05f2ac7cb31af738f95936f55","timestamp":"1779065046707","nonce":"JPEPQP6y","encrypt":"KXFNdwgUcJb0VnnmdYLW6oN4UlcKr+qqGP1AlObGmObNBxb6PupKxD0SsWcG8VHOTRtcTn9K8bnDW8pqc99SU84lV1r2WLD1pSM2UJ/WBXzpEDRIhshJTpFU6/T/RCHOmTuAhDhjT/sfMMrLCYptVrDL8kHWyq9QlBXWkXLwdpvT6p7JiQFasALEY/tC2mrWIrHMOBg3Quky+Qd+k2UvC6w+AEmvMDzotesDrG9kPoNyg8Iv9YbiYmkdBSGOghfxap4BIdBrSI+M32NTSYa3fgPDLXCBZBH9VzfVyRH+9zudsqbwH0RRwcLwi62xzGzFNIJ1bgW7/vYrWG0/XLkkLvU921h79PHNPbFifHW4pMKgs038xmIgKNs5PA43aOitVkkLVTfxsIi0b5ouL4qotirqWzdA4q9R8bXpq0TOnLXj5UExOEI7r8BAqKvipKhglvX562+RXckRsfdio+8gXLftkyP/6EOr9IZMQvqGE/6NS9z7PnPY79wXxDLYXYYF+YkKP6Bm0i+U1RTK2PrnUXy9TZ33C8L0d0qtEg4kN+jAhqSpbQWLGmYgWtkh9Py+ffkAKp0j11xDkJ5/AQ0eTNyIoNjmM3X/J577cjuwbQMwVwvzx7/Xtux2udwN5y1y659hO2aKj1vYHtEMhtkLbZQPab64hWCznXQ3yLMr2OSPzVVIdOZfivLSXVb3B5dgdrvn9yYVQLIONzffSY4NgSFqaM41GIZbpGODUJhtKfs7moxNuwZUhWT+4XNfrL02TngACXkYoXXpQ/BTo3flfqNHhbz578oQT7iBAX00gKAma6N5I+O996k2MduDhaRSYNQYUos4FYPEMJlIOWAuggtXsCTpN4pL+CVoHYxtvCCnmt/sTTf88C4PSqrw9rNMGg7nFAygHsXpDbQej71rQm/HuQy/42iQvPbsV6EKcx0MyOTgqKQx+ngviOZN8Tzx+JfdSCo8SU3hGm/mYioRBQzJJIVRGJ4v7hJTyNj66stYjUPdxukFVp0z9PKoszFAFB/OMeywx8j0WkuDzXC42CZ+B9mAvErP3T1/MCnkOF4="}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"2c9565538e3b46b0b4a237002ead56cf","finishTime":1779065000000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1778925260000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101156217321}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065047037, msg_signature=cb8d08e20dd2bd53f274f44102a6d11531120db8, encrypt=mI5mn+MxHeD4hlBW8N7c7/FPWtv+3gMQw33E+UgzGSZ6Y/7yRiXCoivnNjCuQVaZ1WKEckWXa71ILEd+tD8mSA==, nonce=2kpXyq0M14ie9Nqf}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"508f5a217d52b8c82d50fb9644e953a71a85115a","msg_signature":"508f5a217d52b8c82d50fb9644e953a71a85115a","timestamp":"1779065046761","nonce":"ATZhGQjr","encrypt":"Ga9seFWKfbh5sLt/i2pbqz/4rJ+DOiZKnDO44rJY7X1tud0WbDSk6THp4DAyjhdRL46pR8tF5BjJwHRaJ/xZWP09J914zXC3jir0Ov+IjCyQHTmx2MEiRM6xzTnjWHWKZLneLvf+wFvpxNGUuuJ5jcPCXtpTMAK+r5o5R9qXejETFkxi758EbdnOoAVstPKUkWhKOcnEVPzKygj1aNG5LfnEAHUfiN8PtcC52x5JAHOuBTSBTGjPeEwtQjrYR4yXzGcOQE5bxeK5ZXYomsneHGpCV+lhryOP/fZOJ4Z2Gae0NUm7M4K46l8OlZStvgtvDv6qQZpQLrs3w+JxvIcQOGFfQ7/qKVrX9HlJYT7bJv7dC+S8cyiQ+mQebP14rgllmayZMe+Mi0oZFJ5HVj2M30hvFxHDdP1Mjh1htAgStuxO4Nhlj5oWhrYR/ZpWTBP5wqUKAxrvrMTdkntk2YrmHRVOdPqjlGOxNu04g1MszImbD1XoZjEoZzYjg5G+UIY1hk+lQjEBjBuyORKltplEg7jRP4FShd9X1eSP/8qVEyJsSeGqS0r5sEThmzTM+xd5Y2De52GMZ2/QtpPdf9arGTEioiq4Fs2tdN3wpeDQ5PraHS44ScrudBIsrP3PZCMzPaBxS74WKGedgjG1DYrsst1i95QSgbMM7oD4aT66tH6vNugFEr+5q4mJ8GY6dhM65CDuZ7l+H9Rkziyi3w+HB2GERnexNOCqMQ+x/aHF9ggH6KOg6VBFzbandSXDbqdXWhNH4lghvUO6RHS/KbKbLcwjBSH03oTK9AcaDpojvB9zDwpL4gDLKQ/tAnJ6wh950eEAj1l8joX4l6VDdAlihI6NjC0+Twha4LArMyrDcFjsLH/vt6XLxMT/lalf37j1nsZpqitFAEmU29ufX7vac19Ns0m5Cl8gX311tMW5UPqCVoYUCrB5ima2S/PhdZJ8cg6KQN1QmX8f7FHZ5RhrtaCjJwGuHZluPwCPEgmrCsldDio3Y/pulATxw9miG6Xb"}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"qKnJo9BRRSq3GemBFc_Q_g08411778909461","eventId":"964fc204bc6b4e5dbe5755eaff059ac9","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161331000017243","activityName":"研发技术人员确认提交方案","actualActionerId":"01190846452221394385","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779065001000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"01190846452221394385","taskId":101208140285}
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:44:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065047056, msg_signature=19ea2bbda37a333721f38981d8664edc9aa6b204, encrypt=DazfUoxa24dOQ1soxkwY8RlMK/uxrmLy26HoOXqSau7Wl4W3YIQGw0fBkCxSVKzVHcG//r4survYNJBe5lajzw==, nonce=TH8hU2Gqqh6ZWWuA}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"43b599e80b6a82ec9da5b39a4c5dd211c8b20753","msg_signature":"43b599e80b6a82ec9da5b39a4c5dd211c8b20753","timestamp":"1779065112957","nonce":"WvSX71ZT","encrypt":"EYP5+5f4KID4oUN7S4SL3GO1zkDxrIoMj1uIFCUm6BXIClr1eoSJMB6bUs2610V1Yklt0P+UAkbXezxNsLSRSGG09kQ5Aw1oxB6cdPCa8A8Sd3X3a21/FY6Rz774RzFoTlSrYqtCzNnEPQwz+war8tv9mdmDSjoG8KLC4YjX9ShvORlDmHFQs695KTof1bjsacTr/8yRnwkqZe2j2yVjSKxxxdbmAJjynZTN4c6x+PmB7pmWehv1nxW1vbvG9beBcpqmuKG7iGep01Rd/tb1Py0IEOK0P/2aNmGcLp0juxdQgq0yqHGw5IRO9gasNIFE2H2cx0VIbHepXQZT+Z0OIQ5sA3JKOFDJibt+TwA7GzYU95xgBsUIniiKjvLe78/4iGhpfGXFkSVAFXDts1xwm1GyUAnFlguqzwSqhAyPhXCTVpjAk5ZVPRjgD1O4FC7upsq/Nx/Cmed+HqrqXa4gXeUX83g6/ieqqUi0SGsRoCucAvcbG4zk4humjasFOjDVobUuc7q5cEaaQk2DiCY0YRID6tXB8YkCRBSYCi0KrApivsiu0PlF8m2gBydX4kRjEQbNXb3Cq5ODvnwyhZHS4QDJrrei0vivsEyDSfsNLMxMdCMQF6Nw2ZBYdHu8cxhin7FeplrUL766k7tE0Bmxk4FVLVkOKPD1NZzIUlFHNIaICiSLiubwhNmLKGMp+8B+HDlChCJzPgjVD7/tvs3qE3r/JeaKLG5Vyu+OoOt1RtILxrNP8ZTn/mFf9H0TvlNMwqUmcL4oDoDMA8kDFr5TaSutjJPlrJ9liZym1IhRFURznIHQM2JU0X4wlKIptYy1Itn7iJFgAAdv8xiIOhADa+A4b5jm1V2gkFhjOFMFMZ1rOMcNr+VqHQuNhmVPnhZcBJkd2VIW637cWn7703FYB04ywtCa17ZsLGDPVC7lT08mKlOd5/VxwQkMs1KdudUaRx8YtW5AJ1UOMjZExrW0JQ=="}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"JKgCIslCQR2qzoIzZnUf7Q08411778920494","eventId":"bc5c3685bb93498a919fe06ecaae2e58","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B/type/start","EventType":"bpms_task_change","businessId":"202605161634000544911","activityName":"经营副总","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"位晓峰提交的售后单","type":"start","activityId":"8d29_685e","createTime":1779065112000,"processCode":"PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101102815300}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065113261, msg_signature=505512f6b7ad5c8129e4ff9782269ffa2307cf35, encrypt=8aDUY4z4kZH5cWfjfTiwHvLpBQJQDYjpigceCxAzaNtkaOeejha2q9kEX+tCYasbhwwnYF2/WGe7k4taZXEEVA==, nonce=1HsyEDuPygbImN9T}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"0cb550fd3367bcbbeaed4b5e724fb2ed0bbe2523","msg_signature":"0cb550fd3367bcbbeaed4b5e724fb2ed0bbe2523","timestamp":"1779065113095","nonce":"60fMatQl","encrypt":"J6F3oFqSbAY01+lxPB2mHN/DbUx9bvgpZKhDT8csLgK4yBR5e27CWMlUuxQpvj+7adkANu91SR/SNVy+pOgY9zSk/BqaCkl0Iwzh588VWA+56of25fbno30whaG/f8G1acI4EhsUmNgFXojgD4Dmw63QYKynCxpSAyOnaTrJksGyG2BtP2hT8XmOap9KPeXkamXZcyg4abgxMFAtlCW8cwk4XdLCx1VDk5uaOq9Wfrh485rfkD/H8pmNmQjb/SIVhSed9qMeRNCN1CNxx8fFxNU5DZKpw7+JSSptrE85ugcU4jlCZMd32N5o41VWkRovhz6GAYjF58ZrhGrHJDAHChWXQucnWngf9iYCHp35WRpD1CnAKJSMR6RW2n3Qs0Jpl3Umap3RoOq+jCzULonause2O5lJtt6kgKRWLK2cEaKkEXMYvSoGDhjo/lv/TYbcpY1mDeWbduA1hWV+ECvxWiBAyBahGpxziUUIEZ/TsHYt3nihZqO14ir0oIhqiww55TxDEN6NiYduJ8/nG+J8gTvvC1v5Rg/Dfpiwi73q4YZRcUom9I+Sqq55ee1FugtPk866hhefyWhXv9LXqRVL06HSP6mMrrn0vzNGrZE2Jo8v4yJq7fDFE76g7169XYN1KPZt97WPUWAufd8VmlzAI1atYIRNfEGXzsJ9/RQQO883W4CKBZ9eOFujsT6cOBk6Qb1qHNSAjbQE0OMgBE/uHJFHEjaJt2cOnssUHzvU6KPaH3iZAIEpjaM21G+RLq71gyAr/HRjKLXlI4FleuEaeDxd5jOXxHqclpQ1nfIMum6EnxiMapsug3D0rJSgXLU7wn9K+ZQSjPslK5eb0tkQ98d+FJwWbJVsIUmfGe16syMZjBjBRM5nyFHTIselrlnKQSOx91e+8Jxy8T9TStD94YGdWM/Gm2yvie99zqHsWtU92gW485HmXfaAS64WN9ljivdfUZODWhkFz0hZDA1hujNoQF1mkkYrmPdwUl5ZfJu5Hjm0YROxCe2phhJnNhecVK3YiP4fKTaNNZW3AkomCN434ZDqi8we5jRz8bIE2rU="}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"JKgCIslCQR2qzoIzZnUf7Q08411778920494","eventId":"6502eca8185f4c8195bea87a80abee2b","finishTime":1779065112000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B/type/finish","EventType":"bpms_task_change","businessId":"202605161634000544911","activityName":"部门领导","remark":"同意","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"位晓峰提交的售后单","type":"finish","result":"agree","activityId":"1918_5cd3","createTime":1778920495000,"processCode":"PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101192164822}
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:13 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065113402, msg_signature=b651d7e1c4444e9adf24be61b9e0df96172aca00, encrypt=FB8dufTTc5Kc8JAkw+FHuDRbi8IMVinwZG9H9ipKIsESAGyY2fcVJwFu+Hb7MAZbWuLlEyhsycL8VFYOUhVAXw==, nonce=tBOFL9i3StEMSFED}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"3e58db1bac0ca405e8bbeb90ab02b80475e7b074","msg_signature":"3e58db1bac0ca405e8bbeb90ab02b80475e7b074","timestamp":"1779065132842","nonce":"bIPVo5Cq","encrypt":"YAhZ2QGV0Tcpa3cMi3KKqdLXGHOm5RxxvD0XLar1SGvV3BtoFyo+Gv4JHhD89ZA660Qgw62WSy9zaUwCWNPJnzLXKEJvfRE/8lvyQ4KSaVof6O7WmIj0AWpJZj6jt3Iy5PJ8UM2yo6zKNiiP/9jttQ1sjOCrcAHVU8sEEuh94oho5m59P/MDm9vXHyJ4HjRo9KduEnaHS8quXxyWSEO5eABICLdy3rHBr47EUczxO/Wc4xIXpn9Nu45NqsXE2Qtcedb25SSbNkCeDNlNMm+e7xT9vucXH3VwBeNeZ10rzmn8uaW+ptBZPv9H8QW9QsOk4zxEqSv0cx0E2oKvzgVJS7BW91HaqPjAaM+f3UevzFx73xFKWn/IJqHL+ZWAP4Ov4+tfedsk7n63T2xtWWlH7jk+U3PxVQe6cKrsYwH4PioAB0qnG1xTaxZyUyuZCgMzocW7yDmkyfqr5Jb/Uci8LXC9BBfcaFiXF0RdepajoNhILbt/JHCOZUZZABLUVrdnQ0Dr1E/xxn1ybdtmRWrDZ8WvIC8+VIjsBXcXEv2miSr2xwmQdh8zbwDsWRchXGTXqbjLKidSlIUpyjskgiHY8rU/j+TemEXtg/iZzujjWmiALfz8Hk1Nwud+H9SZ0fw107UHHK91K0+SR+Nykoq5N6KTva3Jf9eDO25F7fPPAW1i5f7VkjBlrRD7UjnKtjTkNbUilJxdmzZpr5yxpP0GkUvvEEfcCVVhQ94y64bIgs/W8rtUx3G6ZGvGB3HrzUBA3pkm4C4H4+bidCzfLLWLvLIf1g89OL3WjG9Hylsy88Cj7vJmPwJreICXSMx6GgzhLSo5abRmSd/y30drbLgrkaBAJA4wEHj/QpQn517/VyM/wmxdvjRHtS0Urhek4G1odkPaA1cPsxykTUxOGNmfbkV7vKyyHtzGkikbsYCcf6O1Gidl2TLF/7N/uUWknqHNsRTueTYuAOlICrhw0DKwsg=="}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"KAZXa5tFTaOO8AtVY2QUvw08411778920716","eventId":"949c5fa9e58945468f8ceead2d47869e","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605161638000369846","activityName":"连续多级主管","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"start","activityId":"d4b7_f54c","createTime":1778920717000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101087267117}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065133167, msg_signature=c06bcbb9e014a31fd27d4269f286df131e655587, encrypt=Dq/DFJK3WUf0+vsVxbCmA3L+CbEx7wa5rxzQ1bQR4FrCYXObdRTZiNP1pvE/MeumYK2+WPlUTFE0NzPUh/QcCw==, nonce=4MRwyxbHvZvuQCDu}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"5b8b4194367686cab0a63614ff83f3136be6625e","msg_signature":"5b8b4194367686cab0a63614ff83f3136be6625e","timestamp":"1779065132847","nonce":"BfBBSSlr","encrypt":"n5X5/Cqd1dsgDLH2CoAVpxEpRRv0LX9wLdfMx+qSBfkT2Jq6+w5IElUA0vX/srGcnpRA2DsoieErXDJN2VrFWocY836zFwtLkfQPr6ayOhrXn4kzVpFds4GKUF6jr1gCAr8Tb1h+ossedvBSnH9gESkn3/5D7R1xOLwULLEMKw2zq98YIroeRqB4QMpl7siPxlERho76krodZ2Nx0pFnxS/DsPCECaqACo/tXInO+Js8/HyrJ80IgSP9ctFDwOEQtcLlXiLrrobu/teI4Or89s7WcUsDe2yIAfkfvCb8yU7t3dBoDM+c8EbGPdBZkH2iuC1TvdyeAN2W+POtdbXTHxnBe5D/jE34LCVRlbqWOMte2zkMPOIzJZW/TSm4Eijg4nIhIIx+bxWo+qqQPYAgwdZDVL1eIvTaInu+fovEMAKUMlKW40VI7314xIXiZr5mzHVvMTdrRFmINOe0KFCPfjNQ0hqfRnjeEgeMSrpGiI+0LD3HB5GtZIZ92FcnjuyIPjnszwFywi3OlmGp0HAP3dLtykNS8ZJRKFOCMpoC7USpltwq2lsRIrfJgC81JMJPqci+OAGDe93QlgXeBKaMfMIR0Pv9YixAuBEpv38rB+cJswdDVQjX6afVRn+atsS2wMwas64l0Q9WGyWcNQeDALM5TojQygPGbUbaY8mpx13SSxuacHXhAJ8rajyRo21/yBC+d+9VX5HOcnT3r9/l2C3NOY6qOHxE4kfRq8+w6CHKj8uDrVIlMqdZ8PO0+mxf8Srh7UYW2W9dOP4jfN8ObzqCmlzCKUXVnXXluJsMMBv7syKhAatIPzVCc5I1iqZIzzq3R6xgp1AWh6WGzI4/wvLyBR+JykvXvOYJNW82nxEoD1STKg7xenRAz7MDH4aRiJVY4Bxm4Ol9HgmnC33Cysgk6wBfB2cysSvtrifj9WEziTWfUng2FmXkxJwC2rhf43xJGK1c1KX/dWRje2uNhReCZ0ulP0xQTqHG5yZB54t8EIQiaGAhOlCByhRQfLiie9Irh/eNs9Ebs5w/kcZG8efGkfF9Wr7E+tbw8+cYFCg="}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"KAZXa5tFTaOO8AtVY2QUvw08411778920716","eventId":"a5ce68c03b9b401d8c7cdb70436ad0a7","finishTime":1779065132000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605161638000369846","activityName":"连续多级主管","remark":"同意","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"finish","result":"agree","activityId":"d4b7_f54c","createTime":1778920717000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101087267116}
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:33 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065133191, msg_signature=0b0f1c566e002900c2002459999a55826722d691, encrypt=VsD9OVb6tPvudNloyIIrNkMM2Y5ieWPlTzMVJG0Nc1VqBNpW/ADoQ7yNC3Jworw4L5czHKHFXvqfBDXCtiZQ7A==, nonce=qrlBiBtlKSZjzhTK}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"c464e1e7e4d359f59d2a6ec89c5723dcfa7d3c35","msg_signature":"c464e1e7e4d359f59d2a6ec89c5723dcfa7d3c35","timestamp":"1779065147219","nonce":"g0yEIztf","encrypt":"oQGmkxECQoLfYUzEoBRWZu3jAxdjMPP1Rv7QuSi7AinNYLXxs2s4/+rEMdasGKVfR7IX43qgm7r+P/kOpN+xER7cqUyt78HnPN99Ct/dyH1Gm49dL6Wf29iXzANLlPdsCitJKxyQArxQXg/2W5UWpvqNyoCZU049M6r137RHO1oKcZLDkKvxCumlKlMbw1W6RiQEDV4Ihx1F9kYdbZG+7fSTBLsiV+Qgf1L76/1/q7bess+5csmlWMFzBG/U9P5vcrJKdm8baQDxleUYzkP9mz2ft4YE93kBkgaRoyzcQwB1wA9EqPqnKvvAVeGBZfD14dmoC1ZqjeQEtuBMQgT5m90zkLqYvVG4HqGJM2Dt7E2cLvdSU2tj20TY/5V2QtvHMk13BuFl76B3tuVjd83niEKSK2IjZvzstRxHQAocjew8u6VAfhTTnUkDEdmeWsvZ56fUjgZPiiXya9ZxOc3eQDE4jIk/A2BAfYU7+5+RaawfOSGIIqfZkjhk0Pajrxrmpy6ZAaE/B/e+prIbKN9lGx6KSFHxFaJlkOq5C+tBPpE3/+fQZjr0T5ZthmWuiCsHM6AhwEiWrSdKnDday2AjVYr8dm2e+D58MRizMtW2GK9RPWiaNIiccLIyQnNZstO61wmxeSMw4vY05IkEEDAP3NZDr/hSOd2PH4zzORncieFfWfD+n7CFpDlDowjWMmuZ+Ss+ky3aQHjE0P5OavmlBExeEopnSBiL7JdPu+5jLs7MK39B4fzHOzWdqXbQrFKlV9g8xhlR+wXe0oZrfjCau+zLHss0muEf+Pb4gCvNb5uG7zKDLJZ8g9uvCi3qUpMUCSv9pEKsKfkxOJR0QS40sMSJkGu1qhaYqKPuleX+R8HgBCrgdXRzDz7JbhFpvvAeNKj8hZEiebkQQp423u86zY6BeZTUD5eJ3Z6ZFk3AXmazdbkcC6s5NzVzH0KuM0Z0FBopouFAUFFer9WBFGJLXaMMakUE33uXpU7vMjaVYkHBZaH752KKdOGFbsgojSqOm1d8sMfCZggLJ7/BPsZPoZMf5KdfY4Vsf6wMrufpfDo="}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"zXa8jMa2QO6JJBnfFHi0zQ08411778918891","eventId":"056e633ae3974d528246939a73ea291b","finishTime":1779065147000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605161608000119008","activityName":"连续多级主管","remark":"同意","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"finish","result":"agree","activityId":"d4b7_f54c","createTime":1778918892000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101154557980}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065147574, msg_signature=9246ee84e9c5aabe7525ead2a9c0b39ae4e7e1f9, encrypt=J+m1HvJSigaBvvS8fssPRzzPsPTRtSLxDLIRTAxm8/g1RucL2yqzl7uBnoavIK6IZeEs7fsab1mYyON7ZNR38w==, nonce=pta5GS7eDDk4alc9}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"48921919889340ad3ba23da6e59c4b4c75bf5854","msg_signature":"48921919889340ad3ba23da6e59c4b4c75bf5854","timestamp":"1779065147327","nonce":"SXOInfxz","encrypt":"dVrMPIoa+IB/nn3T7ef0wm+rFzvF1DmN2AL5c5PGshZT2bR3fHbGOQCy6B0ANTsGO4aVTIdMztnECI4ZQoc1U9NmOqNje9LA/f9BX9I7+HsB5HIOtytrqQsT1vkXflL6uv5qZTb/UItbBTLR5jNIszB/U7Ef500i2vxo0xV4CkyY8qyYdaRRaLcsE3+cg4VHijzUclNELNKQwt7rq8EHjewThgckcgVphT4BT5RWfkpZWBxJQqmpDNTKwmEGlAcOK+uap00l6r4L+TCjWWerB5mbfdPkJTIQnck7qFwJmufqwX1dHO/H5/IyVJWkbx3ayrVg0tD3rcAw67oYXgaP9g4l2tQc+ptTUMjbFAJ/ZedyJ5xo3MfyBCzvfQ1pk6mMP7G0T0c29g8JM8Q98J0RwoHaC2ycf4NPXBLAv49+au4e1aiqfz7+CLbsic86C0oZrA+9V0ZNAUhJGR2R1IYC8pvhIIl9+2uc7je0GyS8ULwP5g/6HVTuiOMVlyFJ3ypqm+ldYx/88pmYc6HUYY450ZssLnIQ58D4MNKygO8MU55Nk4Oh3Ch4wEWy5MTlvdb9tFVSQp8NQ4InRuRmABVeAKhZAV0MQutsOWBaJHjxTomIyAvBnUMu3RK1mJ55qwKjbhTYuL0F/N3bSZkxbGBS39uOnFNn6IntHAFN7kD2dGGk/JC2Opxl1Q7hV4wLRHgMMmyWu0/miU+7efBPgLz9bMkZM1556HXk5RCOlQyuHW0atabF6STqzuotrM7DbJCdTiB8PxOGgeTUnGhJEXa8qSt9ncWTyD3eGfR5af5oiyzta37tIAH+sqgmoKAu1+0XIAPdE0JLjgRWwC131dcacJSA0BcvM8TjJQOv7QD9MVrZzJ0AmYKFt5E+4mLEtuc23zGUuXsE9vFEZ/y6MlrNKv8hG2FOdgY9kJOLizaiGFCRiHRZgY7J+W83YknJKJPJzZoGcHoC7Gty9EkI/7qXUw=="}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"zXa8jMa2QO6JJBnfFHi0zQ08411778918891","eventId":"0d037e11fd954c4cb2bd6a2ba6053cfb","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605161608000119008","activityName":"连续多级主管","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"start","activityId":"d4b7_f54c","createTime":1778918892000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101154557981}
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:45:47 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065147641, msg_signature=6314484061fdff8497f65b1d5e9bebde716cfcad, encrypt=wtMMn5d7xJnVEZ3r3lLqzM1Qz2wJ1ocB/iVWXXiSD4wG/sFzUQxRC/rBsPhHLWXcReXzNUgL+XcayqPTMjCiPg==, nonce=nRQ3eTsPE338pJN8}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"52df9877aeccdfe89752fdd46784be64f52a4f42","msg_signature":"52df9877aeccdfe89752fdd46784be64f52a4f42","timestamp":"1779065223916","nonce":"pkDqn4f3","encrypt":"QOpo7urUo3Ap/Leh7+YJ2cFcD9uKEbO9if9xngyepnaMufZSjFxpAHSp4+q5/qOPJuhoja6kkwXbuQJs4fNgRRz44jR8EeoGUuDblksZnxBEzyHcfal02ya6zmqhsH+la9hBPhRnE68dQBh0TJvuSGfbN2Xg9e95Ca2jkbEY4gGrCj8gm+6StN9neMm6nk/Jj9jPVjEAIqBuHKKWhDhd9x9n8KgLxhqLtglzQVm6gcELDxKkdgFDMkudAUbE0K3vDcys14VrCnMCSpAPA73secxPSfwgvUGOtZ9NWKIKHfUXpZTNxOS/4EwlC/+TXyI7AM5Y7cvTfw1eNJWs6sQzd1BgeLuzKt7LmhXc7P8kGJzyDlXdLLkVS5DsRC6BdKSk4oQrrCnHCHK0/B8hFatAaY0MqnqQct0WthJO2PAhta26IP28VLrPlL64Vj9aPLxj8k2QyW+MRFX0hDAv4sVwwnJJFAz6HZ6tgnCKSqQmgX5qrIKVbBRjXNJghIgpjoi71Zw57e1adAINq+TzmqkBXhRi4BgVqt4j6ULI7OJmt6kv7ALP/k77Hnibaynvkc3vxNPy9EWbk+WV6sN0T7bgC+K4F7CqrsgNMgrvkvnEe93AU9dSezn/2CqD2uQAJhRiNTcm6uzM0gl3dR0XKh6i12NFVfL/EkMMaspXLYjbPRWgn9D+HBimoboptL5ItjNNNrc5q5Yxb0MKx97azLcdqwSftRjhhYvty15lk3JMxz5SnNgcl1NCWRxXkWASqYfAecYeJ58mtLJimyRxwpZK/zacVfJDvZkVyJALojJ0rZiibQd2Wm8mahd+dYr29WDGtIDWCS3/+DsYu2DeoA5/bE2kBthmKEY1Knr2b+Zici213zG5ddt7jMnX/v0guR+1F8RdSTrKgaZWyhogD9hdJ95Fjy+KLX4VS/3fi7EpO8JxGt+uHB1OQOYQddkgBngyXCkgJGes19llvYdafQaNjQ=="}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"dd46634f896b46e7940f7922e7ddc1a6","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/start","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"生产技术部长","actualActionerId":"01201038164023402380","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"start","activityId":"b689_7c0a","createTime":1779065223000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"01201038164023402380","taskId":101102887296}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065224281, msg_signature=f41f941364bfc63ec4b274dd10827c477ade0c03, encrypt=Lfjj3SiD5U6iJAuegr4KjFksXIZTwbjR6IFMY49El+GGDj0vP8cNa+4vmGKhsmLvXEK2etFtkdKC+2Y8y6Htxg==, nonce=CMI2CQIrp2Twir8p}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"2ecef8a28c522ab10e13661bc48ba6d10130432c","msg_signature":"2ecef8a28c522ab10e13661bc48ba6d10130432c","timestamp":"1779065224084","nonce":"I86iOUDE","encrypt":"3iarZzmYF5E2lPCo33753FcVZUwFvMhuobSoZ8DhohcfL6QgR/Ayln1DgSEKkPE4HDdWaA+NeQIX16pMujn7fBIGbfRD0nnab1fPtb3LoXfY3m/DxhkmL6FkGN4iLWiR4YpICjN8CGEBsKz9JbBGga2uezAlCRUvwtnEs+0FYR8uJTdLUUeSDnxtjsMdAhZEiLfNeBvUkcoEdimgsfrovmoJeFpd9qDksNQ9l8cMgqDdC8i1KlQiFK8ecksBa4MZ0+fQckZjjTR5lIlLAwJLpSLMv0vh3AEHOyjNj6QhZhKYUB9UZV6Z3eCpr6bPUpc8lBcSKS2oqSg2g3OjX/JsC9SSsXywyQXBWdkQ9geHBlpgPsxQ45rtCBV9BUPJqgwRjbiTJk+noVmQA3slpSUBLqWuih10RIRIyN/3eq3C8CSgMS3udSXecyb0xFH1KtsK3mmJgbl79tZGQg2v1FTJ2HTi0uiLjHoU/LvXOcQBKYFi8iVSRD+SQ0dckdPSEU1/RfqU4CkP/CpuiBG7s7vMX/x4nU+HfwmlzLXvn+wI4oarnAElse60anGm5Mes/QramHri0iZTJz1Spp0URySOKHmkHzkw18AG5AMFOLXLB/3PoHMHFi2gDw9eNYsoU0okZUNf5sStOfi3cEQPsV2tLccoqMChEk4a9F4Xa1lWm9Ld6DLBShnfT/PX082+4/pFKTC4sDL+o5P+VGqnfXCRweqGf/V867gHNYfdq8qAZsaNx6AeBFs4FdYiz8vbYy+PgdIm/9ymOBqCaTA3+GlWMktTi/ZLyBYQfIEdaPUk2iVm0+MbnswrlnmJmn8i30RNYrEoTpbryEsegwOXZihCjm/Q1NIw2KDxpxGfg7b4QdhnMlnDbPhxWiOHiQ5AoXlyCkBDvQ8v0fUdoatgz/5xLwcg9rxsQ+dQiqRp4PgCpJ4Cj9e4Ca/66mhMyN+q7Sm6V82pm2HeDKFiYixUczXh2q66MqldzBRnJE6TIGYDEvlveNnF6Rx6iGKn2CCX7b+m2eL0NBsHLzguCUHx5Uh5om90an8yrtAfJPb2RbEd8SA="}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"670e81d6f0234f5a846219befe190800","finishTime":1779065223000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/finish","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"部门领导","remark":"同意","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"finish","result":"agree","activityId":"1918_5cd3","createTime":1778914560000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101190804299}
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:47:04 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065224440, msg_signature=a22124125d293d7cd10626e761bf6857b70edc75, encrypt=uBchH/FqAWQfeskoBAt7GrHvYA7w1dISMkIqrI5lyR8GHl2x/MFom3LhMIAxt4FLb/0MBOTYMeyz7vywRub4ag==, nonce=YPMYgQxpioJutSeC}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"fbee3ef8ba676d11d1540486cd07d804c3eee493","msg_signature":"fbee3ef8ba676d11d1540486cd07d804c3eee493","timestamp":"1779065245377","nonce":"BVjV0XJd","encrypt":"Adgsvb2N0fKZD6qiGjnC1+n0bwzzOtfGn+UDYOrmJtPUUPjVcv8ztYCGdI1Dps1NWZ/y5UHCEI8yQX4Lauu2Cp96pi8cW6WbObBqXMyhv4ES1zv5xPIrfa7cYK4vTxlIQtkSfh2Q7Ir/tyJQSmsjkOxoOgtZPyvnRWBVTsuRGEgGw0IdqClhop1WrkHPcNNBXKxPfrli21jF8ApZiyiTeO1aVrO6iAtLzLlTd/BHGeoR7iWXwq5htTYBFLYHaJPEdTBD3kt4AhMjKAtRSycA4RW7hPOS5hhxj9t7cnwNLdecsYlXPNMMGiJI2dFmkMLsQCr+o/vbulVoxA8Ft8QTocG2wAnrDoJYAt1CQytJKyT+mOnw91q1SFKXWChDfkLXqsJFl6dh/KCwlM9KlL6kGiEjGguWd5TqJngjapBecTRP8fpRyAJRa7EG0cegLFqTTVsFYHCHQgaLB8bJT2OrM/C5tiR/tukMdwnBC0w9dQT3WJB7YE4bisjIcDLu8zFi+3RJq30o09S8qdqu6LWOoE48j4xSICCjsSZSE/bWx6p5s14ZWRDmQLuZxFfk8OvMm2OzQoyz1p37pf6wDQCNu1yfJoRVJ50MvfG0rmsFlsxmJya1nu7IcmSpt2/IsL/SGqw4isfYGXPCfvm6sBsaas0bQFoipYLfcE6wQGZqTgre4xKb/yT/m8aoAp3bqSf6O+GjVKSCuUEI+H23gTNt+2MuOTZ4YAzQfaAY6jLJmRJdDo4EDR1QYY3s58I1L4S4/FhGCq3IiYu8a/kiQOYNrIR9pnNA7YUAcdPxe42PQV+xFV3NQgX1QjSHr61xfC+bmeOQw4mrqZjH/m+spjhGx1oPvMCebTlBMxZyVqMf1BRbQRGEpRj6fTJK9SsSXN1t8l6LTXRoaP5oqrz6D+aLNxBz78vy4/dJm98dPtDOdmVscj+2U2iL5er3+ij+n7n5oEBgLIiAXeHKIxsShq7qGIc+rurlqM2r39KXMUAmDFIUnaxiQ8xpqqe9dpS9leSx0Deum404bbbZbFQ98uZuDLVrc7R5otfxc+5Y7QYqRsF4uqGz/uDGlE2hnxWSyY3Epv/ELiKAuVGJkgO8YcKPww=="}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"78489aaae61543c791400bcf2a61e3aa","finishTime":1779065245000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"工业销售总监","remark":"已确认","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"0a8f_4e19","createTime":1778917294000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101086411175}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065245692, msg_signature=b66d57115b2cd3172f02d82ae5a8bbf9bd78b38b, encrypt=96ZH20NtOjD/q+uUzY6Y8F16flqx4t+FETuXJ6x3W3xCy4kW3mm5FC0SsFaY8ED+BZ8S6BzhmEhVu7Oz6uHlOQ==, nonce=eiO4hpwTsTNPgys9}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"e0ed5f51a64f00f8e02425e10323f7a27d3a7eb3","msg_signature":"e0ed5f51a64f00f8e02425e10323f7a27d3a7eb3","timestamp":"1779065245516","nonce":"Gw0x8XcO","encrypt":"Ryqkt9zbrAgHGfWIpojjy4Ne7OXme/Fbe14aDLgHNUfXA4pHj00eVIUX20qZ7+ZIYJOFKi+6r5g0YfP1UZOJVq3kwm1+ijYUA69DOVOdmgaxt4VdCCDR8KWRrMDBgrI5pMXxRUivkt9nkbIzmiKXcVDICN2jo6BjmOBNPcH6HPcRGqZrWbtVQhPpN3TuAXsr2qr+SBfXDIEm9CIUtEDQxn/CHnc619DWvcz/nmtueIn4ClXY5J0jIucBAPhGgwImBZZI68X/EXLANnwQPt6MWHlkdcHHqUPkjD6cC0da3b6zDJB0vJcgo9AKTJ0jedyVnyX+LutMFr+WF7IYX12JAn1w0tD2e7yRBso9Xrmxo9So8HU40uiBH7iqW/NBHcVaSQmrT3re1h8NHneIX4K9lP7ej9TDiLXfZjIyO+DLHG90E/Ff8XnaiPXyNFsVzdOqDuf3R/N62S37zvbkbLoSJtBxDGg6hR2sBrVEK74O2DU9AHR8icoEYXOBD4cm+usjhrCGEmr7FVpbrKmI0wG3HdtcsLOqI3vEjLYDZKLRz/0IG60wZ8YBcDCuFxhP5CfNrxFusw/JVtCv/tY4HGvZVfc4iiY9e5le6cVrZV5Dch0XMkOsNp/PzdcIqUWtMaA1yG3ZQHQ+NuJIHKWrj2Xm29Jzctxy/NXIOaAvxLFh2238E75OupXgLx2BtXatiOSy5HZYEjJXKxR0cUFT6oJWJhXl+jR5CeLHXnsO3LpTtAvuc1C+6B3GJRsvuUXEhaqUhyGTK+jB9yxWLQg8Ik+IwNfFRQ3fUSLqQuxZF5BSoHnUPs8TxOGzwGuLbqZr1l3Bfe0z1mAJDf+1cAeNHZWWCSCyGWWNPQrPjilTREX7KS8JLZ+D9hsWRVHsp/H/csSkKoZ7tMZkFSA+HgtMel4lZQOhlWrL6aHKQ4Xdm6iVbEdb9+ma6a8vYZvNTb67eOFsgeewi6qewZKQEWAXTkt8ww=="}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"ff40bdcf73eb4aadaeadf7de1dc5ecb9","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"总工程师","actualActionerId":"035715651324258877","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"122b_b71f","createTime":1779065245000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"035715651324258877","taskId":101170493283}
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:47:25 [XNIO-1 task-3] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065245826, msg_signature=d1b231538003e524ac299a1150da1278be8cb0dd, encrypt=fj/wU1adumXsK4QTfB7Bydz3YG1LA//fN9vS07TpbV502N4rTkXMyymRqqgSQF4FbmX44KRGfr0uFuZbV2p2RA==, nonce=ONzJVmen26nunLAe}
|
||||
2026-05-18 08:53:43 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"2b2c01930639ffe3abe631165e340335357e21f0","msg_signature":"2b2c01930639ffe3abe631165e340335357e21f0","timestamp":"1779065622724","nonce":"CHYinqHR","encrypt":"ZoKb79i7vnHD8Nx63/8qLYQAfmjtcIEBwkz3uebJTgB8udWAvoQzqmjufh9K0WXwTzvNpmMnI5LihvZXFhe7NuDt5X98UAwxu7Z2ah0QexEI986Y4y2vdfkm/shu5cFaaZIkfodsD0Ojf6vxjoDDIXm3zSFso/IYA/mHBbAVaJngmOOTL1ULmrxlkCFVYp7dmH8cUyGjw/8n4nEFd1KWqECfatxBgJLodIVR5FNw6yjspIscTxPO0e1X2zsHM7rpiaoUMETyEEWV0kgA3ZYctpMIRSNJwrB3FDEDKMCKK5xOgOKU8le7tsT3p5F3MTVGae/2RkL2Tf0OOFlZzTd166aikbHz0wvyR9SdQ3ZQcBdDl/dfid0ezBjVwMPggm8Ctdgyk5HR4th51/tNI8VacLb3M/ojs8dVm2r41V7vRYTLQNbu9/ZBG/XHnhxon9MAGBtk22C9WW1gwmji0tD4hESSR4wQCNXoEKENSeYJ8tTyGSSxxulhEg0z4VNM3KXU+OH+mkyewKc29t9LnzP8Jpu0Xi7oD0hji2b6/x7Bkfc4nWUCkpgrp8fWUcSzVqwjBKZWIOppUTNfqSvYDLrcFSB65z0tkjb9svVZdZCR0vI7wyiDYKVWoOwqKYjBUYyHMVweuj5Bn13GCTTiw1NokShrZWLfadERwk1COs9txBuMcnoBNie3r8e+0YM8SOBY2/ZZkwMHMN9SR2I8DAxu/uaKWjW1s+lWS0pyeN01CGOWTkpEe+Y8f1564yVYry5JWlzzZaXVwx7hiTWmvu7vqvj3uzBapVwpfnQ8gNUtwkb3J2Xan9pdRvSVY8wPXrwdQPzU7IAplfuvTKmA9ycDG/naUrRdmUKNT0X6PEli4CJK7EylRwH1f6nF/ImA47o79uhY6pxBFHhaiApL2Sjq3mwvZ1nviickqei3cBwruuaTM+5OVo5plIA/CcXckFZZeq/ghQPJyLQwW3J6YXJqoMW+0lC7dFO5NlHPSOQ/WmzuaL6wqhzMUE2f5pcN6eqD+T3R5xxEs1R8AmwX83DOg5qKYAAHRyyFBsx52HkWSkgwPXYKRm2fLfM9IjNB0GaE8GQ6em3npkyXy+/nTkotEXSgg+bhC9ThX8gHJbCbMGdvE1j8CDoEiAsX8XoFAY2KJMgmo6Y4i1CMHvZwPIFK5Qxt2A8cpNKcuNOX29ktfl8="}
|
||||
2026-05-18 08:53:43 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"JKgCIslCQR2qzoIzZnUf7Q08411778920494","eventId":"13c86cb3b9c64389a74fd1b8b296975f","finishTime":1779065622000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B/type/finish","EventType":"bpms_task_change","businessId":"202605161634000544911","activityName":"经营副总","remark":"售后人员不知道什么原因,领导不知道原因,反正就是售后,不正常。不同意拒绝","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"位晓峰提交的售后单","type":"finish","result":"refuse","activityId":"8d29_685e","createTime":1779065112000,"processCode":"PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101102815300}
|
||||
2026-05-18 08:53:43 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:53:43 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:53:43 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065623038, msg_signature=87948638896f6edfb996941683df41f1d7b03080, encrypt=SulxTVz3ofISPz1Sd865EdQp6vLlPU7j813LbwD4fgS4cSTuLEJf/5SLNWAtrG1hBrSZitVRVwPyF+cwC4THJg==, nonce=988oDm7M9oK5CO8J}
|
||||
2026-05-18 08:54:04 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"1dd7f1de30e1b596d8f7570c2735a3071cb2597e","msg_signature":"1dd7f1de30e1b596d8f7570c2735a3071cb2597e","timestamp":"1779065644073","nonce":"qIiMFoNj","encrypt":"i/okOIKUrJ4gCEF2biocDgCf16Q/1l8a1y5AfIItvBe3aMlKNbZn+Mjeq5Exevf6EMFk9xduD3t0tGdNNMdrhV3fLhd7KHk5ANImEWXk66Xm6ONykoEBSveiRbuq9xDtkx7HVkqrDeVLqv0mP1nDn3EZWzENIHWssLQgD1+/zzTJ0xfmWGOUdGraWn0tUHImD2fKXozaBMxggBqfjeTOtTc4g/i+/fHAi5tFsv2Ofk/V2j2Kh9AjgMpZl8/jI5/tWj5pm6yY76sqVJTQ9DByklqqNVqVHXpdhE/37ByRMZDJHiu36riQ0MIwziizFVv/yVDSljZiobmsetmxT7368uVbvhokMlN7RHKnOiJv2VdaatMdh6uMmChv28y7ikMGcWRpqXJaBRh5L46tOLAFRS0B3s4PT4I5uGZLqsoGEhv4HWojL8QperQDf5DOkeN8aXZHKyGKUhRxKgCUUT0dWqvfegYiNesFYqWyGazloVnrE2e+ZKq7fcEcn4giR3HWF57HRVNiXwVlT+Jw0EL3hx/KOF+7nDifG5phO9li3Bv6GQpkDDDISVxF/Nf2F5BBzjW3yB4RotydbjYrc4kTKb1cnMwkd/1/0YJErk5/o/cp1S4Pb6NoQe8Tg/Y6XnhrH1sAGL5vFzfElF45dOVij9rftmPnlaiaT/0skHATcjvkyCxa+LLgs2LivC27bKY5RIi3I++yZQDZAJoZ3BApmgNnWsrrQfVLPnUDvkIYGhdg7rFxKGu71KY+Q3t4l+Va12NfBvup4r4Rf8V07V7XKTqoWwblTk9aCNIy2ux7+PjymOsfzrTUjqchXEMXU8PuGdAq8kRXXxJ8Zp4uYB1z3LaX7/8+f6ji+iYBEAN/i5uNMunfxdzI10okUwhO1wL+FD+b8RVf9KqX0TrQ8lVH0pjOUF4s3UufjQ3EIr9kmaVVD4B9SVhbb9IyAx/5F23jXDlisjOs2MZ9xkq9Pz9Fr2nCypPxDmsoz0XQDg8baYcyIH90LsclB6H08UVDH4fihLwbPJQqyP2IeVPLNvcuHeWEUqm9u7slbGEJmNi+0Ks="}
|
||||
2026-05-18 08:54:04 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"KAZXa5tFTaOO8AtVY2QUvw08411778920716","eventId":"427d8baf727645328202f4d6c9d3a623","finishTime":1779065643000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605161638000369846","activityName":"连续多级主管","remark":"同意","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"finish","result":"agree","activityId":"d4b7_f54c","createTime":1778920717000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101087267117}
|
||||
2026-05-18 08:54:04 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:54:04 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:54:04 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065644376, msg_signature=0afb41fca17471a603ac449f9890337fa039459d, encrypt=mJb4vCZwA+DiHUtpMHkyJtYcAOaBcqUHHg0aOQ6ZjiqYH++Raxwfx+STLbvMyUnLPcTw+QBfkmO2/sKBUXzu3Q==, nonce=pTQwUg3wTIlmXwnG}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"1ae3a0351344a5d850b377d6b6b24c666530c02e","msg_signature":"1ae3a0351344a5d850b377d6b6b24c666530c02e","timestamp":"1779065668918","nonce":"2GSZMoJ7","encrypt":"1CPqVmjPZqYrsJzdpkR7ckxu1RzgSApWMaSnRZDKHM2cT7Uoai3p0YKP6iGtzPlVS+Hl8zGghGjcAowYYvibBuMj3OZQqAUxF3XrhJEwST7ZRQy0twOArW/J8ss7En0xH+Q4FVhKCc/u8YwqO4cZzsYqOuIyzMzaRyoQ4OyGCglqgd1U6h6Fony4kRBMvWwRceKDH5QHjJAbmAcn0y7b2W6H0mFStfDWUu96JGUQzAzX6wXloZ2ynER6TQECifCohfWkhdHfJNNeFg7AEzrGlWEpnzTb6/MaY8FkratyPQLoOSrrsXjzPXW+9o2541+hBUGhAW+Ky3CEx2FvDJ9uUVX5ORi6nNcPrP20rrt5EuQ+meKw2FfH/F5L1QqUpkhaIp+2BRqfEyIH6gTDeqcqAlvPkHihZC5n2jqIuluNXDi1BxvP/k7Js1csw2YHyvUkcu8LmomOz8KZIz7rB7mfkAXz0eZsy7iSYiVDiuFaZd4mKFjIT8jYP1kpUzGV/j3Knzl/6LLvJgX6IyrAQw5rACSHn2M0BOv/eggNXZn13GBusehcuUZe1F8EgyuIda5xVa03sudPfJCiOCBfyxHbHG/2N0hW0lXKzTfnGwlPh6g6dIalQAityiZjDzraTKAOkdkmUttl9rtKVI0el2aEzPIlCEcsGftQYM/Jtlyp3RQ4zlo5XUVMh53WeXkkfarxxuDk/KwkZGulK8TT09NIkFBqk2OA/gAPgzBnB+hi0rv/xeb4Do202Fui4tpYyyXgZ/dYPpjiSkX4Ilj7dMGCIOOo7kAjfvra3x6ZUTb3CwxGaMUsh1/+PJI/4z922bHPaq2Q0Jw+osOSTHXvM2+xCFI8stjDEeqpDLbFHsmr6NxAwyg9YJl+Jz335V1/tGPkBr0pDhlw7gJvoL2TqVfkGS5yVS2zz5sR6y/mDMHHLRylefYd5G90/BpA7kUAr+LK7zAgWl4vujfviCPx4d/gr56K4bAaFHCfuSjmZxu9Cl8o/X5ehwRbkFx5w7Gy+3/x"}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"9qhNpt8QQvWwUEY5nXeXZw08411778832037","eventId":"94540b39e4cc4774b8382148f2ce7d6d","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35/type/start","EventType":"bpms_task_change","businessId":"202605151600000374159","activityName":"质量判断整改有效性并判断被考核人","actualActionerId":"173760274129324770","agentActionerIds":[],"title":"陈志学提交的不合格评审单","type":"start","activityId":"305c_d252","createTime":1779065668000,"processCode":"PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35","bizCategoryId":"","businessType":"","staffId":"173760274129324770","taskId":101142674034}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065669219, msg_signature=1f9e1dfa38660b8dddc97443135ee95f1a5228f8, encrypt=K2kpgIUZ5mUCT34f40hJ4PdGAHbxi9DZV05apmThq4xHNyaZ+2FslTnvGQNKmIt8ohDly/HG8BevZUQfYMg3dw==, nonce=wtcBpP5IILlRBNLH}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"4ee84eb25c6275a192e990c5746382d5d5c735ca","msg_signature":"4ee84eb25c6275a192e990c5746382d5d5c735ca","timestamp":"1779065668994","nonce":"WxKNQEe4","encrypt":"xYoEUNgWs3R7a+M5ou6D/A6WM1GZAhxvRqsgmYGNQw+lOIu4TauL0C5acuu++8UKf/Qj4JIUBXKbylwNRk0KdQpwRQsH/sZCLAPqQF71SM86+PHhxMMA6sbqnUBE1V90p9LOzAv3CKlgEwybM3/IL9CImRd4/ITcrgQaZ1+iBkBlLhDiqg2q2Rg3isyjBKO9lXbka+sVmF8Y7HOBiFtlwn7LIeJzIpsCkvY+bXB5aPfbiOYF3H97RTxIfhU2smwvBkxrcHF+T5XHwVAdG3vumVEgGltng9fGlzPYfO7QBhFf1+szN9lZJ0uk86xfDbDWLvjxhDzqoaBe8e6qZwbQUJGdXXcb5oXA2hcHl4oiobuNVp2ExAZAX+6ncySL+kmQHTJzfWDQrV18G71Mii3FMa2M1Ntvnq/xow+BsiCqv7Z4saI9gbADiN6MRJrBrSUI7r0x0VPgE4NHdYA4STXrgxK/qwMFFzSckWGaiSjlhbIOwXpy///+skSTZppyFnoQsGKlbrsDjesVsKNCsZvOtNGvebEeCjNGiDpeQKUfl3AtW7kivk9DM90Ihblw8aaAOeMiaO40JPF2YJwr2wXboSPTvY9sCnZ4fiV9zGnDRVzMxr01J4JIEux3gepcttVH4AerVnvRxej6pf+pO7eFD3bsFkp8xss9wr6c66z0LsNHtCVdmP7cyXol79QQscLUY3OJ1pyOFnhoHZE54UABoGy+OXS+22tL47y7a9qBtXKfxTSqB2gzvFP3SJ0dE5ttjWTFVBHttrN5RvFg8hIXU3U4siJpJgdd4f4UqIzK+t8UaDkComOgrZb2Owx6ciKl4VoeOiwAPCTdnmkVVH+m7hbuRwSQMwH+04lJzzzz/XgKOhnbwdEz71XRMsLlBDM07gdZgvyJihXjZuHY44AO/UT5u2liGVCTcKQ6pAVhl6AXvMeJ4BpDkkcF1D1oMAe3DGypSexscjpzOJ+4bHOMqcR3xXDQ9KCcb2KGm7FPjrcGlk4O3PDBazjZU76XrgdAuWzbHrtXpaaNqcTRucUtvHjKZHapF8BPjrKYhkbl1opPIYSDAhutouCMVnC8yK4KSVjOWA1C5EYNAa7EDMo8oA=="}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"9qhNpt8QQvWwUEY5nXeXZw08411778832037","eventId":"de92ec4846fc4f5f931542c1b2910293","finishTime":1779065668000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35/type/finish","EventType":"bpms_task_change","businessId":"202605151600000374159","activityName":"责任部门提交整改措施","remark":"已确认","actualActionerId":"010858214800672369","agentActionerIds":[],"title":"陈志学提交的不合格评审单","type":"finish","result":"audit","activityId":"679e_2fe7","createTime":1778926412000,"processCode":"PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35","bizCategoryId":"","businessType":"","staffId":"010858214800672369","taskId":101088555729}
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:54:29 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065669293, msg_signature=9c2cbda630fbbc25f3f2a465105de8ada8589709, encrypt=kzwRjo602CCmzMOUYovoybPSroTp8s6nlbZnQNav/Wz1QFWwsPiU41q6FQvtrdn5bpEtibTRa4sdZP4wT/cOJA==, nonce=BKLAFFWqp39M5RgI}
|
||||
2026-05-18 08:54:36 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"26c8c1cab2cd75ccbc72b74bcd005dec8a29e2b8","msg_signature":"26c8c1cab2cd75ccbc72b74bcd005dec8a29e2b8","timestamp":"1779065676034","nonce":"osQ7MDHZ","encrypt":"myIB4x7nS3Cig8dBtje90/Cl3yNCLF94KDLVbnbrOHDEXlcinmSTUVdp0Zgkt04+xUExJZTYwjQwzMRbJT6AU9qEnaRE2t8SN8T2CPWQiibVd53LmAF61uQ6bj4QOdM68SpF/LeIHaVve8ouc1RzZRluqD1ZfjMTYpZ6NsDq5jM/sX6VycBCReHis+AI7DGqLvQcVs2IG1v6sNzRC0h+LlOyz/daocC3UwmNX1TP/bVB8o2kxo4MLIMvIB3+riDhsvbelehim1kiTIAOEKviUmhE/bJLapb3FFfbAZOjq/Wdrpptd4GzAO8bHAe9nH6u8UojIpGaB9mtWwow02Q6rIokVa0TnGMSJsy/ZwaaLZTAQ2OJaMlc9cqXzP0gdoghVC75o2ptpAnKSQyhqa29nAmNK6pYIFISXR9eOCDvQPUc3oS7Z1A9gCfrUqYS2GRF1MK1AbbKv6jDL+tp3uRCF7PTmUCs3Ymb64ymSR4pDcC74GEytiEWg3P7EaiO0Ifp1Iv+jACeT5C8wWBEdkvFKdkSKrnQ1xmtYem7LUDjR3Ce5v2c7bMKLICNuCQPyULdecF9o3c2RJIH2xv77XPOqmnZHeEH+aeC8JoiBYjbbrJ/f0w7oGYfWnAt3Stc6E84cs4ylw8/JS5MDjDtD2LWeTaTbtfG7aDE++KA2ICw4zrl9MZnq4RUYOXJKDGhII8SHzAgayGHs+RMypCo/yzskXc/H+bomL0tzgjMvLa+czE0dHAsgo0rj/HOnJ3Mf26xQw9BPPU8VmdMtdIPazPkYv+ptszszR63e8oj5TA4+MTymxMtIGqXHLK+IfDdFGAjeRTqpgH3dGAlU88l5Vjm4OT25/ioVRHJ5C1yrRtoKH9KIqh/BVdP4NlbxHT4PhurhebNvLgkwJyXYAInufyYMzTnft++zHtPX4te8hqbzsStm8HjiUCmDj5Ju6fYsMSNA12eUt50ozMDSCD45esF2ijW0TjI74mDnxpzukgdQDerdUPfue6Q5YqU+OZYjn+pzAVdVVeLNJdqE6fkzami3pvPu+BSO1Il3Iy1Pj/yMVI="}
|
||||
2026-05-18 08:54:36 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"zXa8jMa2QO6JJBnfFHi0zQ08411778918891","eventId":"ec58f397f8ae4aefb24d964fb8175b63","finishTime":1779065675000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605161608000119008","activityName":"连续多级主管","remark":"同意","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"张茜提交的用印审批单","type":"finish","result":"agree","activityId":"d4b7_f54c","createTime":1778918892000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101154557981}
|
||||
2026-05-18 08:54:36 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:54:36 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:54:36 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065676341, msg_signature=f5668c057606cc3add687e1751fe0a7b815317a7, encrypt=gixHPwlB/55xy/EiWjcrLgd5pcWb6wpw6eytldvDMuVC2zN1eJEvLEcApMVPmP5r/YoU3EbyAjItgbTki6G/AA==, nonce=TWnq0NhjvjAx6Zub}
|
||||
2026-05-18 08:59:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"c7c3a36c26d029e8acce2fce406af5f1b2f80e71","msg_signature":"c7c3a36c26d029e8acce2fce406af5f1b2f80e71","timestamp":"1779065947099","nonce":"v0cORoWp","encrypt":"OsbQzle+3f5JCrxawIGnHz/tYa3BmGCCInMZcco8saENPjhhePsLin9g10c6Rj/X2QDTQuqDa4EDA7y7EmZIAtp4IfhCBySMQ+R4I1sd0qClg1EK/s/UQj3+HCErvavox8yJ//gulBQXOkgaWviHSfEpxLynmhzKXvbsRZkRhMF2+VExVxLEoyvzxqZmW3Q8p1DrlgRHRaFcQUZYzWEisaZsvJxBWql8bJbfbk9rWjZy3YbNy2ShqNE//dyu26OSHVCDpOyebUwj626UX+F1JlHDcbFzitOBscaftV77YmYZina4VUL+zattJeeKkBBF0zDYDC7D9t1/VbYlvRjP/toiYFVVwSfpO4fuNlw9sI34dVbnqeW5egSXFZ1UO9r/cfsGwyotmlhbt7/xufS1yOnGVOVEK+y5CGhWibqZg/QlIuD3VOaPFGnNbEu/W1JCHzAu710AUy9hjFJKsq/d2Q64fQTyEkctMvA6TNKVrpsS7P4GNi6PG6t4SrtQ9Ns9fw4jMYpoMorlL4z2JJyJCIfEqNihkzlTXQjJDHHdpQTBYc9ZiITj+cAV+fjHfrCVzs12uN0hhbgokwfCuKXgSEfcJD3CV1/yES6XqaRJHXyUeU2VTRSCShOQi86zus2NsOixVpHd0tHMGiqyD79XKi2ybzVjbprzJN3Aj5hN2VY539UZtLcUZq5g3IsZpyi6xlN/9JPUtJsMztmL9wrBnw1pgO/Ib3/kKvPvwe2sv1+xfIEjGwIy4Yrrr+Q+cvoyheWndZ3RwuY/kIJWQvNWXBu0TCVMjTxaiLkC96TfBAlo1NygxEtVh/Qo3EMqh1MAH9o/5G7lzmGoRWOE/Y3RtXWQugIqPJcXzjBt65kHhQB84VXvK9jXjVEuVeiQPi0VON1wIVRT7vGEzFAuHXVKGJlU74TOp06XgXK+p/kJxV9cDTTPSKtG0t+jOyJFq7NGREHjR1oBqLilnUlCOvfmHQ=="}
|
||||
2026-05-18 08:59:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"22nH2X4WTzyyzkctrJ2LKw08411779065946","eventId":"ad1caa439040490595b91f076b45af5d","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B/type/start","EventType":"bpms_task_change","businessId":"202605180859000065828","activityName":"部门领导","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"位晓峰提交的售后单","type":"start","activityId":"1918_5cd3","createTime":1779065946000,"processCode":"PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101208612829}
|
||||
2026-05-18 08:59:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 08:59:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 08:59:07 [XNIO-1 task-10] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779065947422, msg_signature=f7b2bcd39c67b81f50f45204063ed91bb60fc073, encrypt=PMbMc3PQS2CK0tDfYO1qvwQXjUczZUr1W8ll5CqTMIy+6PL6RSCzfvtzfB12Cdcy1tSMfttJNZq0x81qoGjyGg==, nonce=VzB29LRvrOSs6yaF}
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO io.undertow - stopping server: Undertow - 2.2.24.Final
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO io.undertow.servlet - Destroying Spring FrameworkServlet 'dispatcherServlet'
|
||||
2026-05-18 09:08:43 [Thread-44] INFO com.xxl.job.core.server.EmbedServer - >>>>>>>>>>> xxl-job remoting server stop.
|
||||
2026-05-18 09:08:43 [xxl-job, executor ExecutorRegistryThread] INFO c.x.j.c.t.ExecutorRegistryThread - >>>>>>>>>>> xxl-job registry-remove success, registryParam:RegistryParam{registryGroup='EXECUTOR', registryKey='xxl-job-executor', registryValue='http://192.168.5.200:9101/'}, registryResult:ReturnT [code=200, msg=null, content=null]
|
||||
2026-05-18 09:08:43 [xxl-job, executor ExecutorRegistryThread] INFO c.x.j.c.t.ExecutorRegistryThread - >>>>>>>>>>> xxl-job, executor registry thread destroy.
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO com.xxl.job.core.server.EmbedServer - >>>>>>>>>>> xxl-job remoting server destroy success.
|
||||
2026-05-18 09:08:43 [xxl-job, executor JobLogFileCleanThread] INFO c.x.j.c.thread.JobLogFileCleanThread - >>>>>>>>>>> xxl-job, executor JobLogFileCleanThread thread destroy.
|
||||
2026-05-18 09:08:43 [xxl-job, executor TriggerCallbackThread] INFO c.x.j.c.thread.TriggerCallbackThread - >>>>>>>>>>> xxl-job, executor callback thread destroy.
|
||||
2026-05-18 09:08:43 [Thread-43] INFO c.x.j.c.thread.TriggerCallbackThread - >>>>>>>>>>> xxl-job, executor retry callback thread destroy.
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO c.r.f.manager.ShutdownManager - ====关闭后台任务任务线程池====
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource start closing ....
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - master - Shutdown initiated...
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - master - Shutdown completed.
|
||||
2026-05-18 09:08:43 [SpringApplicationShutdownHook] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource all closed success,bye
|
||||
2026-05-18 09:09:09 [background-preinit] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.2.5.Final
|
||||
2026-05-18 09:09:09 [main] INFO com.ruoyi.RuoYiApplication - Starting RuoYiApplication using Java 1.8.0_482 on LAPTOP-AK2JCS84 with PID 67076 (D:\evo-k3cloud\ruoyi-admin\target\classes started by lenovo in D:\evo-k3cloud)
|
||||
2026-05-18 09:09:09 [main] INFO com.ruoyi.RuoYiApplication - The following 1 profile is active: "dev"
|
||||
2026-05-18 09:09:13 [main] INFO o.j.m.auto.MinidaoAutoConfiguration - ******************* init miniDao config [ begin ] ***********************
|
||||
2026-05-18 09:09:13 [main] INFO o.j.m.auto.MinidaoAutoConfiguration - ------ minidao.base-package ------- org.jeecg.modules.jmreport.desreport.*
|
||||
2026-05-18 09:09:13 [main] INFO o.j.m.auto.MinidaoAutoConfiguration - ******************* init miniDao config [ end ] ***********************
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDataSourceDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDbDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDbFieldDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDbParamDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDictDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportDictItemDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportLinkDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportMapDao }
|
||||
2026-05-18 09:09:14 [main] INFO o.j.m.f.MiniDaoClassPathMapperScanner - register minidao name is { org.jeecg.modules.jmreport.desreport.dao.JimuReportShareDao }
|
||||
2026-05-18 09:09:15 [main] INFO io.undertow.servlet - Initializing Spring embedded WebApplicationContext
|
||||
2026-05-18 09:09:15 [main] INFO o.j.m.j.c.i.JimuReportConfiguration - Init JimuReport Config [ Token Interceptor & Resource Locations ]
|
||||
2026-05-18 09:09:15 [main] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource detect P6SPY plugin and enabled it
|
||||
2026-05-18 09:09:15 [main] INFO com.zaxxer.hikari.HikariDataSource - master - Starting...
|
||||
2026-05-18 09:09:15 [main] INFO com.zaxxer.hikari.HikariDataSource - master - Start completed.
|
||||
2026-05-18 09:09:15 [main] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource - add a datasource named [slave] success
|
||||
2026-05-18 09:09:15 [main] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource - add a datasource named [sqlserver] success
|
||||
2026-05-18 09:09:15 [main] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource - add a datasource named [master] success
|
||||
2026-05-18 09:09:15 [main] INFO c.b.d.d.DynamicRoutingDataSource - dynamic-datasource initial loaded [3] datasource,primary datasource named [master]
|
||||
2026-05-18 09:09:15 [main] INFO o.j.m.j.c.JmReportExecutorConfig - Init JimuReport Config [ 线程池 ]
|
||||
2026-05-18 09:09:20 [main] INFO c.r.framework.config.JacksonConfig - 初始化 jackson 配置
|
||||
2026-05-18 09:09:20 [main] INFO c.ruoyi.framework.config.RedisConfig - 初始化 redis 配置
|
||||
2026-05-18 09:09:20 [main] INFO org.redisson.Version - Redisson 3.20.1
|
||||
2026-05-18 09:09:21 [redisson-netty-2-5] INFO o.r.c.p.MasterPubSubConnectionPool - 1 connections initialized for localhost/127.0.0.1:6379
|
||||
2026-05-18 09:09:21 [redisson-netty-2-4] INFO o.r.c.pool.MasterConnectionPool - 8 connections initialized for localhost/127.0.0.1:6379
|
||||
2026-05-18 09:09:22 [Thread-35] INFO c.r.c.dingding.DingTalkStreamService - --------------------------------------------------
|
||||
2026-05-18 09:09:22 [Thread-35] INFO c.r.c.dingding.DingTalkStreamService - 正在启动钉钉 Stream 模式事件推送服务...
|
||||
2026-05-18 09:09:22 [Thread-35] INFO c.r.c.dingding.DingTalkStreamService - ClientId: dingebfrpzqko25vo8w6
|
||||
2026-05-18 09:09:22 [Thread-35] INFO c.r.c.dingding.DingTalkStreamService - 钉钉 Stream 模式服务启动成功
|
||||
2026-05-18 09:09:22 [Thread-35] INFO c.r.c.dingding.DingTalkStreamService - --------------------------------------------------
|
||||
2026-05-18 09:09:23 [connection-pool-2-1] INFO c.d.o.a.s.n.w.WebsocketTransportConnector - [DingTalk] start websocket connection, uri=wss://wss-open-connection-union.dingtalk.com:443/connect
|
||||
2026-05-18 09:09:23 [main] INFO com.ruoyi.job.config.XxlJobConfig - >>>>>>>>>>> xxl-job config init.
|
||||
2026-05-18 09:09:23 [connection-pool-2-1] INFO c.d.o.a.s.n.core.DefaultSessionPool - [DingTalk] connection is established, connectionId=3493760e-5256-11f1-a582-1a02b3fe6148
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:updateMaterials, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@6c54d0dc[class com.ruoyi.system.controller.ImMaterialController$$EnhancerBySpringCGLIB$$33481d46#updateMaterials]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:insertJDMaterial, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@5b5f06bb[class com.ruoyi.system.controller.ImMaterialController$$EnhancerBySpringCGLIB$$33481d46#insertJDMaterial]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:outsourcingOrder, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@7c74ef4a[class com.ruoyi.system.controller.ImProductionPlanProController$$EnhancerBySpringCGLIB$$d23153ee#outsourcingOrder]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:procurementOrder, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@54519d74[class com.ruoyi.system.controller.ImProductionPlanProController$$EnhancerBySpringCGLIB$$d23153ee#procurementOrder]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:shengchanOrder2, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@1ec96512[class com.ruoyi.system.controller.ImProductionPlanProController$$EnhancerBySpringCGLIB$$d23153ee#shengchanOrder2]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:updateAssetCard, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@3d00c2ae[class com.ruoyi.system.controller.KingdeeAssetCardController$$EnhancerBySpringCGLIB$$bcb833e#updateAssetCard]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getMassageForMultipleWorkCenters, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@665574fb[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getMassageForMultipleWorkCenters]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getMassageDelayDate, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@3eb7ff78[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getMassageDelayDate]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getKuCun, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@6b83ec49[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getKuCun]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getPurchaseOrder, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@50ad5625[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getPurchaseOrder]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getKuCunTo40SB, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@1d921267[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getKuCunTo40SB]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getConstructionDelay, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@1c5f6292[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getConstructionDelay]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getPurchaseOrder2, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@684a34f4[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getPurchaseOrder2]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getProductionOrder, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@52ec5ba6[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getProductionOrder]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getApplicationMessage, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@5f606ab6[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getApplicationMessage]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getProcessTransferForm, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@384cd83a[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getProcessTransferForm]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:getUninspectedData, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@198a653[class com.ruoyi.system.controller.KingdeeWorkCenterDataController$$EnhancerBySpringCGLIB$$cfd8c590#getUninspectedData]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:generateDoc2, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@3119fcad[class com.ruoyi.system.controller.WlStockDataController$$EnhancerBySpringCGLIB$$2fe52dfa#generateDoc1]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:syncOperationPlanningJobHandler, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@6d7005e2[class com.ruoyi.system.job.SfcOperationPlanningJob#syncOperationPlanningJobHandler]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:demoJobHandler, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@33a39d7e[class com.ruoyi.job.service.SampleService#demoJobHandler]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:httpJobHandler, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@77cd1f67[class com.ruoyi.job.service.SampleService#httpJobHandler]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:demoJobHandler2, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@94f79a7[class com.ruoyi.job.service.SampleService#demoJobHandler2]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:commandJobHandler, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@647d3279[class com.ruoyi.job.service.SampleService#commandJobHandler]
|
||||
2026-05-18 09:09:25 [main] INFO c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job register jobhandler success, name:shardingJobHandler, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@4b9a1be5[class com.ruoyi.job.service.SampleService#shardingJobHandler]
|
||||
2026-05-18 09:09:26 [main] INFO io.undertow - starting server: Undertow - 2.2.24.Final
|
||||
2026-05-18 09:09:26 [Thread-46] INFO com.xxl.job.core.server.EmbedServer - >>>>>>>>>>> xxl-job remoting server start success, nettype = class com.xxl.job.core.server.EmbedServer, port = 9101
|
||||
2026-05-18 09:09:26 [main] INFO org.xnio - XNIO version 3.8.7.Final
|
||||
2026-05-18 09:09:26 [main] INFO org.xnio.nio - XNIO NIO Implementation Version 3.8.7.Final
|
||||
2026-05-18 09:09:26 [main] INFO org.jboss.threads - JBoss Threads version 3.1.0.Final
|
||||
2026-05-18 09:09:26 [main] INFO com.ruoyi.RuoYiApplication - Started RuoYiApplication in 17.632 seconds (JVM running for 21.041)
|
||||
2026-05-18 09:09:26 [main] INFO c.r.s.runner.SystemApplicationRunner - 初始化OSS配置成功
|
||||
2026-05-18 09:09:26 [main] INFO c.r.s.runner.SystemApplicationRunner - 加载参数缓存数据成功
|
||||
2026-05-18 09:09:26 [main] INFO c.r.s.runner.SystemApplicationRunner - 加载字典缓存数据成功
|
||||
2026-05-18 09:09:27 [registrationTask1] INFO d.c.b.a.c.r.ApplicationRegistrator - Application registered itself as 08432fb0b14f
|
||||
2026-05-18 09:09:27 [XNIO-1 task-1] INFO io.undertow.servlet - Initializing Spring DispatcherServlet 'dispatcherServlet'
|
||||
2026-05-18 09:13:28 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"d613a1eecc0a8b7f64b9e39228490550a2cb0e39","msg_signature":"d613a1eecc0a8b7f64b9e39228490550a2cb0e39","timestamp":"1779066808573","nonce":"CBMOmOBX","encrypt":"kru77HtFgKrw8HXEK2B6nZ3NzXXLX+T4Km7vlvpItRkjWKaBYFCjpL4/c7mNxbyEZANhQpjW4XJdMRNhJ0wwBGJ9WCXRI/t+Ep5WvKvzHGEvUYe+Y6dl616nhP+p4YliAbhTdo/zyv1FTj1aENlSOXDitZmih5nvPAki2WbFlD3tnrISKBJQh4zxAoczoyvzUzn/kl6lhC0T49+sPecATuYt8/dufTr2pAvJ2rdPx4Yb3bMPwWy1YtHygdLpFdnYocNmRgQtIZT8lqPgIc4FKOmIrbNcStMjeUnXRQb/hY9N4AeVff8DH0KzQV4BthcFQ7B3VqDgf4tr6q2aAH47k2KvXRMzxVOG+TwbOFnrjynZVpoVDeav/6za10xL6JyS+eUd3giDs93ipLnnsxTykA3vinBKeETyRoMwQxLvz+QnK+2ia2szYah0LvS7e8wFKi9HzsOpmEyZzICkvs7flBTh/tnRC+Wb5NnlmPixXHYgF5hOqdP+gjWpT0p4zECCXjQQi8lEpGZJqkoDqzLGEiefoGdQG2fp18yLZk/O1PMGKZFkCR5fM+qcosMPS+yZaUyRkNc3EXl8tWkeUKCMbsgAvTkWzj8PU8KFHSAzCzdirVb7Sr13+tk4XUBEKyg3K7MOLxH/J6TLkMXWKcHOuAhqp9IkZAf//FqzpFoeCkiayBvZsPUYFQw0O0hTiaDFdj+HHFd2l4Rk0ehY5dhipau1d6hb1gBzAHAosCLPYAkUTw9v2jbDSo+nTSX0hoZZ6X/iUrAbYIUxGBO4iEyoJjLAakMXNKNQfDRQbIJ0zlu6EtRvdCwjVD08cXNcCkCDy60I5b0/FYZmrzs3qVI8Jg=="}
|
||||
2026-05-18 09:13:28 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"632548b4eaf34895b9fb3aed324c2782ab46043e","msg_signature":"632548b4eaf34895b9fb3aed324c2782ab46043e","timestamp":"1779066808463","nonce":"7CMejZCz","encrypt":"XSdqn5mVA5ZrHht9bqx/qTuEQ5mcQLNFYnR1b+02ylTTliNsmdKRx3Ecv8BVyRtmUKJ8uA46PNQpYOyAXgM28zAMSFGlqVTqggAkmRoi2p2C4RPH8Q/OAVhbQ2zGade7q6d3N5X+CAAbZuj1dy9O34u1+p6ciH3M4O5B3+h6EGUmsxxzJKJMNLVyURk4wC5NxHU0bHiIDjh7Ir4W+GyWmnp954r+SRrNK/6ieTtrEN9TGyDxewC4xbdCu34d1WzIc4RkWDQm6Ge86ZzroqMLxnqHVhHKXpKj4GFdbYrQFB7vcEm61myYpVoHCA/OavPlHr900Iu4aIAv4xWgiirVhv3Nspu/14axDQN+8PGMy4OcIPmgdDgFpiY/MsdUDeNt+Sv02Y/j2ORgqCUJvP70ht5PBIfnWyvmMb512EvtANJLyZa8E6pZZMIshxMkCEErxVgT17WVzoDf+6mamik9joyNOc/qUsaaArmFi2emMa0/GReNAcVp8j5tycJNuDq51BBHSRG1UwBvScI/d5VKBe1DRAoluP3RHxTbowRTpgKcLuJsupKoDiRYnCcefPrtzvQpoJyGrGbgS2+6pizNRk8PAa3gKyORSC6CL0tsJKEn+FxXKlISx2FbS/ZZiMw7ZGVcZL9GFZTo27AmSlgga7sZk5DR/FNhizmrtqpdpFbPuuV1j5+RIW+LKH+r/yZOICNX+zbhjc6dY8nseGiBwMz46ZR1mdrttjxgIsXuxgOy/chsbRhDaV39t9ACntX8laibfICOMlcWhZazVrlF9jnMaVhvm/q5V/RRf9VMAJxYmPQ7xHYZ6vbS9muaAQncmLQPoMOpZ5sJuJd3jpAmuQ=="}
|
||||
2026-05-18 09:13:28 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"yOda8XN4STGkd1FKhjUfeA08411778912977","eventId":"2dbe6eec793047288bc851e8258c9718","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/comment","EventType":"bpms_task_change","businessId":"202605161429000373885","title":"田志阳提交的技术方案申请表","type":"comment","content":"管理员后台删除","createTime":1779066808315,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283633411029629036"}
|
||||
2026-05-18 09:13:28 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"zUFBG2SXRZSqspRumD65YA08411778912762","eventId":"10c58d08c6dd4b59b815f4028b26ded4","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/comment","EventType":"bpms_task_change","businessId":"202605161426000023614","title":"田志阳提交的技术方案申请表","type":"comment","content":"管理员后台删除","createTime":1779066808153,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283633411029629036"}
|
||||
2026-05-18 09:13:28 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:13:28 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:13:29 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:13:29 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:13:29 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779066809043, msg_signature=05c89233a706719d0ffa504d34068020398f1003, encrypt=VECoAXl2siR0YfApd6H3ipgQQ2YRBYRU2dd7e8FIZ42auBZ0JPehjUqkwNfM4ltzQbqh+7hYp+UOhCEQOz/ZDg==, nonce=xUOZmOtk7EcJcvne}
|
||||
2026-05-18 09:13:29 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779066809043, msg_signature=0fd3f9afe0ff6d53a495ff87d270ce7f61cc3aef, encrypt=aw83Tt7eqNIpuZRnr6yRk4ehjSxmY+xY5r3NLSHd+8k87dragsdju292kEvFHUnE0iLe/KFmDIviejXGeUfT+g==, nonce=l8bbUqL7NrRJ60P9}
|
||||
2026-05-18 09:16:00 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"de768abf89ffa91c4840818397fa918473d08c91","msg_signature":"de768abf89ffa91c4840818397fa918473d08c91","timestamp":"1779066960606","nonce":"00YrRphr","encrypt":"J74WvfUGX6HVAh8tz9Jb2uv1qjClS+1fN6h/+q75fvSYoKIWQILTAMTM93vpUXqgcL39CX1gsayzus1/+4p4kNYM7+kjlj1DfUM23vBKT3ygs5lzu+PfNLiCDasMkEEVZnujxHTwPCepIwmyRqEVAaIQzxx4u8qa2ZSDckrVyNV26XFdJDOA1YOsiBKl3R6mdwJiTeTLXNbCJewU2QS7boDEIAvONqExbHdDYc7oyFYGCu5CFK6xG9+00fHXkDvFPTLIazfM3CE+TngyagyDksi6subeg5gExHIR9Qm60H0E72DenP3gDe1D3IcuFitrk5xGPi5oeGcPYMDjjJnXaKBYlL6rTYsk3XgR3Y0PjNWVLrQCIagfTDGIF4OifRpbMjE2k6bjVf3V2b0rMXgE7gFr7Gzgn8+Ef0xBzNDc8LbE/XKFjH3Vx2InyCVlFQUvj5rVHJIdp9suqUmWZjU8jrFZbTJzVnxLJFG5jpDnVplkA9w6runHsYPFhnoLiCI8IIVDXKK+1u1h7/TPPp6PW6YaGZY1LduFNi+ydTe5zagn3sXc9Ve2NXl8BW3hgeQQt7gHxnGQ/ECWCyE0SIgC4klSYOpBWcyVyYiWk0Ds7YbElgQTdqyI/mw+0F0W+viveU199nSluwxK6xN8/Yxlpsf6kn8gd0LXvBfBd4STOKBrviwVq//F7iHrqyKtyqLfrm9wuET+LsA0/MXv6KrtD57T1dDkInG6DauxRaLPrYznWwTrZepSH57WipEijgYwF49gF8m5PFKjEgR1jVWa1YWpajNygsT0rNOzPGbJlbLi1ksE3AC8z82q7uqwTEeRW5GuLKT93h5aIvCW3tCRnKueM4o025SL3zjYam5z5fgwdx5Wcwtrrkz7anc96h6dJU9y9A3U+qRuZDd6rjASFRibFM5cH3o4HuplnEu//LLDS/SmBs/FDQyDt/KRBak4eAUt/n3tTKzNgU9WRwqwSQ=="}
|
||||
2026-05-18 09:16:00 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"T_XBf04fSpujK04zZMJXjg08411779066959","eventId":"e94970a436554d6d95aff2a0ff1c7860","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605180915000597802","activityName":"连续多级主管","actualActionerId":"223241230721375124","agentActionerIds":[],"title":"郭亚曼提交的用印审批单","type":"start","activityId":"d4b7_f54c","createTime":1779066960000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"223241230721375124","taskId":101171617644}
|
||||
2026-05-18 09:16:00 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:16:00 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:16:00 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779066960938, msg_signature=a24e789606ecf7cdc834b89c235dc991ab391cd2, encrypt=P4uhcdQY18l6+1q+XABswan23bydTCEnCR/jYgQvJtcLBnjhOreXaq3q8/Wrlhb64lu1Zz7jgOKb1WbSKdUnGA==, nonce=0M760ns02gUMq6he}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"6530c5e6db03562fbcfa79899211c91846e170c4","msg_signature":"6530c5e6db03562fbcfa79899211c91846e170c4","timestamp":"1779066981492","nonce":"YbLpCbWD","encrypt":"ts9NUjJkK5BEtzFzZybZCb9jUiKTZ3V/a48xECgEKEJEkrjzEJ51Liv+Ez3F52sRrdMvkyUR9o6BnflBFFC4G3Uv4cZ3aYIzpFHEB7vU3gFlnWXx9mmzfusF7X5V4Y1DTKv4pBFxnjpcx13N3rUwFVqyCnamNdrfdrN33fH/Qa3iHk3gEqDFZNpYxX9diQgruTfRvigNZPNqPPFFc9k3iAycRa5x+gbVosffViBGfYEhYEpTtAQFPpY29Fk6ipu9vh9JE9K9l77UWvx4uDo6fhdmUM8xKZV87W/A88V8ihdS0Wor2RojdI0/apg4oX/9ML14FfBBmqcHA1ctNVcjXDz2++yIvD/04BtrcR0N3lrOrFCoWWJHFLe9xfTfjZ2q9YBROb/P3ZC0h6lskjYxwezs7N0KcREiUj9Vexqu1p7RKWTwj46JUqu4NNaqzCk76yYC5j6Mq5WMO7Le/QCUaryI7PQD7vGY2pGAKFYTiJNstcXxZ99QB/PprBofx62ulrso1iqYVFePt3ovY2m1uc0rJCq+xUM+NuLFAiFhPUOmYRvljR74u/Bwq46mcZ1YR8ba0wKtX9dUZw/QVofup7arsnLIaiLHUwnt/XSskPalx3mJ5//7j2psOnGBCtj4DAgQ+4LpOi4if+QYUsxAgvFghydWIBqGIxa5kIuuKvGGWYvlOBJWa0sYWTW+uRK52aR7FIli4OsZQfoyypw7Ohv3GhTUzxJNzoVqUMFlzqI5d2M23DD7voWIT67wiaPN35pCawqQItXmtQn4a2d6U3ju9TCqIbktkMV7yVhjGM5vjNFnSAsQC9+5mBp511lksqK8M65LLN8rfpMZ7bA0KxHf46X9XSiyNL+liG4CFOCiThjkLlcr/Gz5WW9onkADCXmakMMbAeyp6QOuag2jgja3/1aE2ovgUa/9qa/AoKmov1UhUtP+UFz0144XqOGcin96OiK34iLrIgRqfmXSOg=="}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"T_XBf04fSpujK04zZMJXjg08411779066959","eventId":"641f34d6ebf3483f988d77e6c6022ddb","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605180915000597802","activityName":"连续多级主管","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"郭亚曼提交的用印审批单","type":"start","activityId":"d4b7_f54c","createTime":1779066960000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101171617645}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779066981796, msg_signature=b2a4b2230586d76c7d540dd38fbc3793f3a25366, encrypt=Va/S0mpJUo+YeHAYiY795sKMylZavNVCsqyLCVb9T6UYtqhAtc76O2UlW9ht5Sawb3SSVCYU415NsYe5yW+ciA==, nonce=fvZdndRBzcypVeRe}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"31e65f4bcfb710010f9bac2c91a7dbefb38ea6a1","msg_signature":"31e65f4bcfb710010f9bac2c91a7dbefb38ea6a1","timestamp":"1779066981569","nonce":"ilX4w96p","encrypt":"um3mdq457NuU7sOByV70sCPykcFNi6AhsLv4w4y+rxdG+2v/rRpVeNXXYMbsdsjShSJdYoa6HA1XMl9gLJzXEp7JiI2OYg6RtUSwL1YjeTNhvny/otsHUGjrSbrPNd0op/8AMIjLZl7NXmGY1JCw5KwOoHsOMvFDMUdfPVkhA8gJGj5tM3FWg9tNNyC10Yrd/WJ/Pt/NxAYMHQPMtB2oxuisJNarkqiK0jvTMWBeX6uFjmF7l/PkoiZ/HIg7hJKqhIqkSA+iOGFzf0j06VNrjNvXcC1b5CvapeDp0bKHakeoXY1+5tsDQXeaky/3vsH1C1Xc88D1JDJr9UbBPh5fZwhrrgZ52y8cmHKIkWesYfiUCo+hbrAaKne51MBETtBajm/TQnpNDXOmYwOelphIRX1GKIlESAkc1PLoc1RajYIdbPXhdDVptsvH6lsScjJYguJePLLVqG5frNwA+CgZSgczJ19PRk85JiBRYLy0Q1plQukfIIKnBz8L7QBQ2nVnluqU3GlbnwdoDrW6vQ/l6kofv7TTAPoA3cgmWOe/AAcIgl7ZD6ciZv2o/GJqKEZn+R0oiK7JkkELNaWFrkaTU0/p/HAmRUx0gtNXfa7y/KmfOyejJCtxJnpQHUd0cRV4lDFzJDhE6WQZQOqWa9dXSIx38629Wf+j2Bpcv+9eYIJ0p9B/5q6Isrv49ynMeX5Vum7X1tX6tll6Cuv9Edih9YJcx4kk9kIgtYH3cH8op5zSKHGfictXN27fyxjCvhygjbsl4m6ix4KKsdYSnK7ko4cEaA+nHO4mWYoyHSmi6NvtB2h2fkgdIYo7akhn7w1MfQ5RsjWFLqJN8dT/rv8QLoWPk7+/eUQdH92/oMGgr/QtPCwVONcv3KpavKNt/0zgAo1UiqoYqMz6RF1gUBlZuI2oBtlp19ar9jfcwmSpgVtccf0CuQnaHouvLYJOwMVy05W0lTFepBC5WrFYydoozJzDxCPaNKy09hkZi3jl2hSbEuk+DVZ0k3FYlrXwPulsrw4Voz30/MlX6FhMpsRfY0+a0U/wf/9q94PkaduHd5A="}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"T_XBf04fSpujK04zZMJXjg08411779066959","eventId":"bb2d94df682141e1b186d6dd7890a014","finishTime":1779066981000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605180915000597802","activityName":"连续多级主管","actualActionerId":"223241230721375124","agentActionerIds":[],"title":"郭亚曼提交的用印审批单","type":"finish","result":"agree","activityId":"d4b7_f54c","createTime":1779066960000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"223241230721375124","taskId":101171617644}
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:16:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779066981864, msg_signature=84173f8439d351d1ed3f784b423b8e11ff523334, encrypt=vYgTZ3hb5TXnX1aZjKNKWQTHMW1Eu1PkPQBiHYtQCrvD1TjkoILA/Gm6iJ4edVsYrAx4ECk3OAiVqZlkMUCadw==, nonce=xg8fiBgv2uz5LvJI}
|
||||
2026-05-18 09:17:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"e5aa047c984a90d36b5eb2f46f877249583829a8","msg_signature":"e5aa047c984a90d36b5eb2f46f877249583829a8","timestamp":"1779067040748","nonce":"34AM3H7o","encrypt":"eREhFZ/t61DYNCipWpe0ZIBRPR5OIadrVotty9RzzQlSL2U+SY79Umr1VwvSch3NhfkHDKwq0uPia85fm5QK8tJpFsTYgra5g4obPH0ygSBGL1QnmQsxIC01VKERxtB6/7yCVHklD3KhbLNBdcKMEz4cfEBVU2tGNAY/NKMt3Ifb5F/hC5P2yj+w+Oplf8NEKot51IG/DIUSsuoY6JHLGsBXK1K9ynsFvMZvNPc+cWDTWlVQNax+XdxQHLjZ37FKO4Ljx1yA5gt/z9y0RNigNXW9fNcc9cZlCMAzDVjsi7s5PTnBK3bYDqwuYz+4RBtJkKXg5cTCcvD+7WN22Qjx5gfB7mZApo809xXH4DO3agUCe1HluExGomu2HYrJx+cN4+mPvB/zTkFxbdTi7XJBdnPrJ76UfegPzRCGreBZKU8/HLZ1l8jwZGh8tVYjlbyQf/i7aP23Se62YUX5298yyBe3rujW96p6E3PMhrjbC3OzEtvnH7rJSqoHb2n/nQSUYC00a/kKBRL1BiMfT6QsoDax4dy5bxYuRWzwzGZdNEJY8BUMOINil7abIrIWbFqEOw/zrXuTJEQVJOz/Eb8bbPc8Ioo9F9tWT6xkVwaU8psoFeYzqW+3MbkwKn6sWese948ag1zpJ7cKrgQW4V7NlOkF4GW1g/PlrBx/KDWoSvmlpO77IifhDmVlCQeppR+ZgyT/TAdAwMh6eWajiWQWG/T8f5ThkDvwmP3UdhZVHEubNtMNHYofrDuyZpnvI0+i8IJE13oaXij5bBputKoQbef+1GISlYVui2fYquLfkQKpwSk19QErXFDjWuMUv2mZtbWbVmirbr0Jk1QWPeev6LoOxodjG/+oLfrPMsjdHgpbkRd7nQ9Ei170ZePqsRL+QhvBHcGjwMqORZdJNZ+wghaktdgqy0kni3CaaIKxZACyXUiUAdAUxOo5GFYoVcEhCPReUbO5jsTI8iWh0JCDtw=="}
|
||||
2026-05-18 09:17:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"mSJmSHiNSNulT_2pRiVZ1Q08411779067039","eventId":"c090a273e6c94df3aa991f38775c3c7f","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B/type/start","EventType":"bpms_task_change","businessId":"202605180917000199559","activityName":"部门领导","actualActionerId":"02580952260533396432","agentActionerIds":[],"title":"位晓峰提交的售后单","type":"start","activityId":"1918_5cd3","createTime":1779067040000,"processCode":"PROC-FDF3F88C-ADAC-473C-ABCB-9EAAFECABE3B","bizCategoryId":"","businessType":"","staffId":"02580952260533396432","taskId":101143434454}
|
||||
2026-05-18 09:17:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:17:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:17:21 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067041069, msg_signature=36e2848888199fa8dda4e75d457b413d7ef6e814, encrypt=lYpJphlN/Q5fTGvFEChPphUfN6z3RIVj1aqbGs44uPSJkWDaP5jgEGs4poz4t6ERvSZpUDgZwNoAvYTKgFW+bA==, nonce=Frpio3kiPoRrrzju}
|
||||
2026-05-18 09:18:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"18f2d1ab815106b50068fd47a55178a76c850099","msg_signature":"18f2d1ab815106b50068fd47a55178a76c850099","timestamp":"1779067081444","nonce":"6neqbdT4","encrypt":"VDBhlLGXLHB2Sm9dWs2+slyAl1j2pGfMOLhOQOS5kdmXKBLoGuzxtpCI97BFrLZvMA9RHRRGcC+fqTgsfSxBH77O5/BhGKOrICiavcijstYzEHRraAgzz9cOqOOtXVkLNuWQoDq0kyiOobmg+/CBiAHH/hCoFgL5EVkeC8V4p0GmExHyAt/4To8ACZyaRVhjlNyNlM5Zku3VVvx7DbHQvf1OV6fEdV20S6MEo3IXOZpZvBMMewDQD4KyBcHCmpsCDAM2EKA37ue82iey6S/ZZMs6HzyThzw0oukM44ZQklkqvkqkLQ9wAbATIoq6oT1CoitepuKme8Xe518kvmwcyEfHCVOQNaF92DKRQhNJ8YzlWJOAxWEmZ1+brAXO9ls0+DqmPCIWZ3xB78+Bi1HBLPJn/ai7uNWyBR2U05cPuifFdmfuNII1FXf9SzlfbE0c14SxqKBDdLaT2Eo1lHvuRXLirUW58FeahR6oNmYmnY6O0qCxukqzgKfu8Bok5jArY3UiJ0rY2AKG9gedGb4UGVEpfdD+OLGabTyQ23YPW/ETx6ZhoOHhIJKB2sRmnfqigBuBr58F4fyZNLL2Jf2yydPw4KVShQ51Lhm7IpINRKfp/ASswjYJjJ87IoRFzpvmFBxo7SXgwI1A2VfdiVEadgmVtbyEkkgEwh6N871aLuYu/2AASXktnHLNytkEuOCULOPQvqQ5RaUaSln1UTv85Ce5GdA0Poj5hXM6HyJjT03uvbGOW3+YkOWxD0ieSO3nV6Nhoyqg3EGQqx0qMf7aDOjrFIeztxPPUlo6a6WTuuFxDdEREyDXa1VmRp/u7lHBiQD0CLcc5KeThNUZi6+ejunhkK4fs0bz3/yZiRhOLYH1EQY5kM1fa9dCBqj6IBojCTJ4GOcDTUNDEGL6oiu3xhMAjZNRwqKexlCu8Ud4m2ovzXbEEhtszF+AXslJkGFb2v0KMBRJ3KP7ecoOYm8Ykg=="}
|
||||
2026-05-18 09:18:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gddeuwPJSviQZ0EElvuQlQ08411779067080","eventId":"40857a1cd58f430f86e4dd6d108c89bc","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605180918000006850","activityName":"直接主管","actualActionerId":"176735225223967751","agentActionerIds":[],"title":"薛浩远提交的用印审批单","type":"start","activityId":"19a5_614c","createTime":1779067081000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"176735225223967751","taskId":101104191675}
|
||||
2026-05-18 09:18:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:18:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:18:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067081757, msg_signature=aa74302484bf47cbeef948d63318638f0bef6a6e, encrypt=bukD9pOiJyR4Kyfxd6XU8DM55Jz3pfpl6xqXV2B+5krmdvuPahhh0MDNEjN6FuxXD7APtmd1qLaMvpOiMX/bSw==, nonce=lAeteB0vqeNGu1cb}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"262c96163121a7ea113446558be6fe16dd26917e","msg_signature":"262c96163121a7ea113446558be6fe16dd26917e","timestamp":"1779067251234","nonce":"G8gHDeov","encrypt":"1M+UZ7dv19vVLpMFDeQDfYy8RJuXII0i+otwJHCA31SU/QyEEHkIQ4ukD3hdgerJnC0M92ke55DYDc5QcOV2f5hVA6URgvccXkuh6jvLTwY18xOA1mDMepB7Uj1cVDhILIhnrDzMweJZJx68TI5Idtir7fFBodqxYNXTNv8w5Bg294D5VRjFxUzbFCmUzb6J6PXLPImah1L1SqWzSVS5TCW3t37Xs0pvRAR86nD+5qfWyUJhQzLHdJbl1l3zQVaiMs6o1VHnPJkCQrtUpECSJAUKc+7GHLgowRENBHj2oPqSm3uGieCZaf73Txzzdtcs1KyHef2WLPsQ+MTpHXeyaHsCjLI+7q8qea5QTBXB9ES+KDdsXnMB6MD2mu53UA5YCjq1EomEhCkaAZwQgai8pDtservGpDfjgKdgOFi0mTpJVoSwg5NDS0OLaSIZdhKE+93tXDTLqHMK7qSQzuKjQwZy7zCWtPbar1PxZZ428dyM9O/+0Ja92ze5MuCJMmkHhFzKS9xrU+Ud7w+zjgmkEhdkhIZ1oCozqUPCvZ8r16ViXgK8ZvoyDmTfvhDZx9n7X0zIHul40koaTBja2Em+BMWo2KD112RnKf8rYTCdO2n1q6hqae8ghQvdZfx014pI8Vg8ofjv6F3mhZOTe2PQ365sFNx+BIT0PZcomse6vNSmokQtL9J0vQYvGqO4Q5GPMyYsBS809+miK32it1oWgRj6Dhf7DZZVqQRxJrOGV6Ikg3G9WOaKKfv8prqtS7cAkfgaWq2omXRuMybcz8Ia8RQSdrm3U5kLNFshw4UftPpxzAlP5snryRZOxEwCW0K/X5GMKrVf2zgftAtYkaJ+73RrtNLdsX+y/QVZkBR/dEleljloHlHqmwmhnQPfbN3hLHyJB4Q6pmHg5Fs0TjzvHcFpaA2kWaKBAk5qxNyfsOpaCQjF3yJ4K5iky2hs94uTOi/tnI7LjYKadGmEQNecIQ=="}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gddeuwPJSviQZ0EElvuQlQ08411779067080","eventId":"b0a54bae49b7411891c291d17d24ed9c","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605180918000006850","activityName":"经营副总","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"薛浩远提交的用印审批单","type":"start","activityId":"53cc_22ee","createTime":1779067238000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101104291687}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067254535, msg_signature=81509d43f545e547f8ed00618ace07017bf7b61d, encrypt=5EuOq6CbOFG3jwd/SCWt0haaOeEbuciEU2wk7aBF1VgIbyISXAYs7DUdu/tKucKM8gLpciJ9duaP+vhxS930jw==, nonce=31UHeKDc6Ld0OOFx}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"32d87d25df5af7e7ac439fde94cdddd27e8edf3f","msg_signature":"32d87d25df5af7e7ac439fde94cdddd27e8edf3f","timestamp":"1779067251272","nonce":"ovcTGUSx","encrypt":"jea2Pr4pR/QVDB6ln+Y+N8JfahT8drdxfP5TAQwGPVdOkaKzM6+51mu3AznLS8utHd+WP3m6uaXwuvJoQGTgF1Bh3LzN6aAfRsiEIJ+F4YGb3BRn713yv+qLgDg3xg2dShbkwnBXo6cjPjCt+HNjoLZ5OkVOT7CRP7dKnbbd3fspclovDUU7uqR/xddtanCxhETj98DQQkub/sagJ1Q/82EeyYvCuXRsrB560hOWF12VE44IrBvddCKZzLKT+3xcKOgZacEuF8preBCp8TJkbJbQklUdD8CG+fowEs7pRhWf2h8oItzogD4OcyyTvZfsl2LW/cNIUq767+7TN4tKkQPDZja7fZLWLFSSjd3fZ7OGGt1tBxFVAvzQtuWU/ZyuScvzsHNHLd7BvZQcznCxSEtc5e5Zssvn4D1ViTJyLw24HwhFgNrkHttW3kzl6VSxiZwwOWoAQxMbfOPXLcUDKYIPzm60byI6gchV6iwQXzF/1SwPTkbi1XqWVjw82ChNbyIXLvT9VftGaNJQ9SXff3p3oi2r28G92bA0G2zJyArdLd8LrI7C7Y20EY83ewBEfBdYrJU8tcjRQBOxH+upEXT1XBQxzPlrJ9x5gFD/4u2Zw3nImtsj7a+GA5Op/ppa0AWYS/US2zoQjdj9SAqvhI2p1Fh4NaKDoAEvW++jw/6SP4YFO/htfx3H1VL1UsWoS6/UCEFbdPdqs6Cg+Ryb/Fg/6sRhO1k8p9MgcNnG9mN1sI1g82TC8uCeEl4e3Lvyc2ynDoOTmy/Q/P5IyT5KElqREFlodhkpJw+ACPsCWskii7glOFTYfZfS34GgvGLYAHVr8Ed0Cz7IAIWDl2sbrV3kg7lL5/5zCB4HbLTJ8mDSH3mMtKoDdvuYU1v6EGD8v9brbq20OGPOisFNwCzmreWJJhchlYh5RwoBWLSBKYm5ufGfW9zuzCbpbQeQ6UdAPGdvkaryezFGM0n1kh2IiDZxIn2yqACFmwtJJRDstIF65FqT5Qfb5i0WLChVQYfM"}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gddeuwPJSviQZ0EElvuQlQ08411779067080","eventId":"0905c3a6b665497da41a3150f99d87d4","finishTime":1779067238000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605180918000006850","activityName":"直接主管","actualActionerId":"176735225223967751","agentActionerIds":[],"title":"薛浩远提交的用印审批单","type":"finish","result":"agree","activityId":"19a5_614c","createTime":1779067081000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"176735225223967751","taskId":101104191675}
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:20:54 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067254568, msg_signature=5880f0cc6bddcbc9721166f5070bc51644e0db62, encrypt=+/88qIB3oEJ/Go15XNcWOEh3NGtTu+nPnnZRfcOnwgPtdDz1qKUnPoG9mQ7B409tlhlmlcRamFFL8t6JmwKvEA==, nonce=PkBtTU5XmpbTNuRo}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"79beb7d5bc4e36c0fbd34265f3d2b6c9263c3e82","msg_signature":"79beb7d5bc4e36c0fbd34265f3d2b6c9263c3e82","timestamp":"1779067283866","nonce":"h4dSHx8u","encrypt":"A6XARVAgEw96SAkv+2sAr4oFh9Oc8nX9p/wE71dHJWWdj7LUSKc+gn68oJ9duxQMRzGfs0Bh6IATm+pmT+RrOb851f2f0HLmXp18aOYRS4Izl0qrwJTaU1yQunRtedqwSGYIEvGgCWNTkEfrBKo0nkWuEKP4kmAn/zbgGaGP7MOiHZpF4l+zZuLr8F3+5UjyuJkf+EKfHh6NyY6+YdBzKFxtexBHtXsGtrnTQYRQt0teM7E06v8BqxooFsu7XfrlInu5azNBkY/2vR0lFSWWaWxlxg2ORjC95i37J9N9etWibnZcm0uhzfZgT3jjHavMELZLqzUaJGPSWGX5NdXybhW7d0D/Fm/sbJZ2ADNKALiltfGzfD4hSRMt5sg3og7RnWS+eIIBCoHs2LeELHYRyIpLc45Hf2qGCQ7dLiUrmXhVn6a/EhVnVtnnEJicbbfou/ddT3VRl6WvKkVK2fjMi9W4DgE3SlaWny+KJC/utHzJfXs4wohqHKwxzMF+V8YlFrnJ2+rdLbnlahp0OTrSjpT6wzV1TVVL4BQipqF5hHtbchdnxggOeKQ4EHcdVpIiWhp1ek9W08Xccb3rQMgwzdshoO1xqLgnLSXuT7i2EHAWfuSa+zUx2ROjosPtptPEoXbvkjI6As5s3DFMMrRZkaPVV5UEId5bd4cTYKtZ5gtjDE0hQFZTOkU1+uUXgHGqDgSdid64sAz9I6KMq0cLXjXDer2MtK0tmydVYlRZ0EvwWF0Np0sY6IXMaXus3iceN38kNrBwEq4UzHeJod4rJum7rxnzlE43R/ylw+j6ixtUPP2qi67TRTlwQqtyx6hHK7R2t7p57k8igVQAFuNFxJIZfM1OydpuGYC2TAb6oXKkIgWTh5M7qve88GQupZN+LTT0VpvPKMfVbDJjGstxpcqR0efjZ9r+wr4u0GlPnX0TE36IsL7WfLlKpwf3mcBVq3qP7MCk++m9ujV3KsaSqejTSuXUCQU2YH4AGpO5tu9CyWz99OpTME8ucOWnMFNw"}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gddeuwPJSviQZ0EElvuQlQ08411779067080","eventId":"0905c3a6b665497da41a3150f99d87d4","finishTime":1779067238000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/finish","EventType":"bpms_task_change","businessId":"202605180918000006850","activityName":"直接主管","actualActionerId":"176735225223967751","agentActionerIds":[],"title":"薛浩远提交的用印审批单","type":"finish","result":"agree","activityId":"19a5_614c","createTime":1779067081000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"176735225223967751","taskId":101104191675}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067284173, msg_signature=95204a48785d04eacc16151d1878a733dc752134, encrypt=yyo2Jw6aMJWTOO+bcNysFULpTb/YtF9PlQRw9UJAH74BEaldtNI2a2NTJYTbJol73nzxsf1r65oRPaOu09xh/w==, nonce=krm7frOO8vMr9uHN}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"8a82e0e44bd62debe4164facde6b8b71356ccf0e","msg_signature":"8a82e0e44bd62debe4164facde6b8b71356ccf0e","timestamp":"1779067283949","nonce":"PwimurBf","encrypt":"akmLcPwhc1zipMYclAr9ua8GDZEQXUCY6jMCyTl3jAIm4hFbwubzhrflz3rctA8x5Vr4KkNbUYC0AT1K1dVzLiFhnDQuXWIGEfR2My2PpWWKqpn+JFbyI7kG75wRk6wc/I1MLRRMdpQc9+yOwBegs6nmcawC8mVaOkYCCXhKQFvom/KbLujkD7j26pAUE9KEPSdGhnC6y+n6S5dumiovCdmiKUYO32OzfAO8XSBebPSlFX1fdPjqWPPAbieRVsE/kKJMAg+ARQKj2YTXXKBNFcF3GDgkBsGtttsKEY9cHr3Uma6fpxBuLeHorTUAg16P82YpUkFVYVkkxKTlm2EzNAmEgzOodjU4WcjQeXhBX0VSiM5LHkHyWe9LzsXUTPCiTmTVS+IKCYoLoinBE7xikw+XLS3+ivnrS3oslICsu85OQp59dL7Ai1dvZg/AQmH5OpBAGUywhwH63gvFi3rkzBvBNO/ozUNOwdR12H+WPmtMKyZAXJFs17yAROEoUldqR/W4YRko0LLQNqlIfrRbOLB7nXmR3rRYXrg8VTSw0TsklyRbQ2vkhpcXbsYtUp7Is/p/laRvne/knhnxFlLmXGpSrdOFC1NLQ1HqV5wziIB2buKRQxcLISqBNtLaPa+5MuZ7/BeycjsZk6waWv5vdbBppU6+EZ8PbGrPgUEkqLSL+JVp859FYU9XBX+jxNCH/BKgwG1e19zu/M72rlk/NsWTmEpMtXIQWxh4L3SZXs5MDySp/e/hqobaKBjn3k/5Of+vysn90z7QdrZz6i3DUQlAbdWiklNmIqv9eJqZyaxP9uNHp3phgpxiArbmA1/o9ser8Uvh6QrHsUdpohv0KMGSrMZFvzwMCoyc95QRSs5QawEzNz/oUYegCJUzD0fe2CNvbKYfaGG1MDCKqWOpG87EcpKv+Y/BGnleitma9xjdRGJpHCl66JWihn98aMstvnnvmjOC3ATpu7bXLrSAhw=="}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gddeuwPJSviQZ0EElvuQlQ08411779067080","eventId":"b0a54bae49b7411891c291d17d24ed9c","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-FEC37380-3410-4EC8-8638-17844A89DBC6/type/start","EventType":"bpms_task_change","businessId":"202605180918000006850","activityName":"经营副总","actualActionerId":"1017253114780847","agentActionerIds":[],"title":"薛浩远提交的用印审批单","type":"start","activityId":"53cc_22ee","createTime":1779067238000,"processCode":"PROC-FEC37380-3410-4EC8-8638-17844A89DBC6","bizCategoryId":"","businessType":"","staffId":"1017253114780847","taskId":101104291687}
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:21:24 [XNIO-1 task-15] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779067284284, msg_signature=1060174513b1905783b450de2a1635e1977ac428, encrypt=pY3434wnokRJGxJ8KvN6g5UJ5rLPBkwogBf/Xbpu9OZ0L0DP9OZtGm1U26wEWR3CcrgZh8cc/qQZt6i4y4xNbg==, nonce=WV40VadIIx1jKbWT}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"00c7089e8749e12ff92a76e3617ba29ddaa294a5","msg_signature":"00c7089e8749e12ff92a76e3617ba29ddaa294a5","timestamp":"1779068038432","nonce":"VB0SXe4w","encrypt":"iQMOsJsL0p9y0qmVG61Yc2AYK9qV33ybWiwJbeHxK4Sh4oYOrpvLLp7l0uQRLjQL4tKZwgxUDXSbuuHku2LxaeEjukwhJXdZ+ztBIh71aubzIe00kZsBeMnSmRNdcSlt0GXrKc/iKYRY8rGmePWJPGdf0rlzrrXn7+RkKvWEcuAjO0Mn85UplEz/p755M6ooalQFFbzCTq0iuw/6qX2Txe8oOxzTm4HTppag/2hXZWcEbpiZfNICTEpgCrXjCx0my2Vi+kgJ1TohPFmW05Yjq47bLUY78zzA5Ae7fnyz+lB57XJFwmVkzlSeWVkipL1SseSaDiesQZ8YSuf5jWnvpqAPf00FJSLXcSTZpk004QWICePMJ57mNvU1EXlMwQKCnzuRO97pMrgPE5k/Da52muDVbaFQzF5Xlc1SY4TD21Bsws51hDyInoHf4JkanmKwHwL8x+ew9czbMZdOTJy1nHPFZ9NNeLe8ncSmr+jeKmkaYio2fSxy8GaTN/7E8QpBogsQMH6JYX8HsLkoKWyR95mpzRCxq27Es+nusuNXitITvKkhpdiha7ZtS+aJcO5q5z+ev/zt1G9Wm2uII4OVWx/LmCuxGrIMWe5BAN0pWVqb/Jlvp5d1wULlcdNpIrG0P6GJ+tFwipCC01KbFSqyrG8UrRD1qqO+uZalS2MzahzmLqCse+hIVmHjm2VkCW4b7s7LB2Ep8zZO6/8bTGtZbRdyJSucIPP+bQfjLypGaR7wRSxg9vPE+8Z6Wz77Sl2cMo5xD4EslEGBch87yBIRj5+gnKMuJqrWt8nWQ09Hyy1Q2NGl4HNmnkJ9cDN7kOTfhKdz4sVxiW7FrHq88mfroMvOSsQu4dVq3wIoArCjLuj5SlZDOzNpR1hLZTI2ztGwuOm3ihi8lA3S7BXyAaB67fnq3L5A9M2V1S2ybttCJcY++YEx6UFXyjDt+2ZxafBRo4KADM8H56baag9F4nM2UiAtw3NVINgnIM+J6AjMcOH9ZcF3VsCrn1K7ZqEFcYerEPwJECJRaBpIlD1f/rcy9tIs/EhmYSe+FJ1BiQj9RVs="}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"18b267ff3d264935b88704f2622951fe","finishTime":1779068038000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/finish","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"生产技术部长","remark":"","actualActionerId":"01201038164023402380","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"finish","result":"agree","activityId":"b689_7c0a","createTime":1779065223000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"01201038164023402380","taskId":101102887296}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068038774, msg_signature=48eb20770cb5445821dd9acaae49e65306a3fbb0, encrypt=ZmMNQ4SpTt1Y0HTZgHb2uP4JhzVwhn1YZyCAPhX0MCepAC5pTDqih06n1b/PY9vZ7x7/h1VAGcqrLwN5gaxW5A==, nonce=sPBq3nXBDERbzrjQ}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"8af1a580c87d48ea0dd6589978e8b8930e5c0cfc","msg_signature":"8af1a580c87d48ea0dd6589978e8b8930e5c0cfc","timestamp":"1779068038580","nonce":"OVfazdyw","encrypt":"YTwbrOaceTAgRRY/SnDdB2wqiGYftzaWk1OulwAO+HLms9oYkArRLGPfXXpNRgjqGrt7UpVeGHmp5Y1nywGHS06m1XrcwCA0QhCSozp2PGpe9xUW3a1fepv4H0zeqaFwAnqPz6J+6drYDERxha4Zuo0TknvRaL9QS4eLPSGC+sm+XHe1/RvDcS2sOuCetBbE5kbwvrbeSDLOmahOJa2K1N8ZEU5jypgXxvL9WaaTy8xS4fjJa4aRFLX2DpWBq2R5xJ5vad61lwUMOu0tbkUvg/oqryAi0UzH4Dj44JKn+jvUULBKqOXzn/5pJO4fJpL7h9TlBkH9Fwh/yxyhoiUu9+MO+YA+qthEgeF8jK5mnYI2f1sGXCKqQc19RK0cgdgSymYLDNajW3WvGrdMqOV3DOGXi7PZdTviYccRQQTIuSQ5af6Cr3nbBXAeXVTd6ziou4mcOfntzwbLRQGPj4YmLAq/0B8g8ccy7dl+yZ5S8bqOsHE3+kZvDrJLSnpI7+TJBjbV4jr8hCAmZzwKilUNCs3b3FxHAsstNqrmvX4ETmsg/kJshwHJbv+bNVnBXuGiffR9tRbFcSCYJRkNqMz1qwTynjWf35A0kolM8VReuXeaXXNSH3AupnsrDR6SBuzaZAmajNXW0ebroiHsAtCt3X4FExjvoqlgUY3BtxV4doBkPrCBMSSFTHfXkF6wjf2nI50xnXFTSvP9B25UYoI8aXbp903H3l0Zl43Y38lV0biRzrLp+PbCJFIObpdcW4J4pfq6YbF2OtTH9wIsVLOLu+IQx8ao8++E+RoY0kklYKrrdbAc6n/ARC0VloLEPGzEiso0TOitJT8aCUVOQ6XMsAkRnS5zcBtZ+ol9LOk5xJ9lAJuNue0Bu+KdFSt8Fy9nJmucm9KHviYLgiAYyfWX9kP1cxwbTC0CpH0D73vWmRYF0H2J93BkZKb3kLP2XVY/JAc5IuC7apYoUbIWG6cQ8Q=="}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"b3dacc863f0f4aff9db33192bc73c90f","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/start","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"副总工程师(非标)","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"start","activityId":"d81a_b76e","createTime":1779068038000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101144070875}
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:33:58 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068038875, msg_signature=429091eef1a6ca0859bcbbd7e39ca09f095a5fa5, encrypt=PQYxENQScJIy8rbitFKYUpN8s0a8Feq/aWzu3FHcXQhnKKs66yGp/14KHNUIuWjW7V/a50rhXoktnvAEC16u9g==, nonce=28yQkBs9gIlBYNzw}
|
||||
2026-05-18 09:36:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"bd29bcdcefcfc9b1c7d9685d5f5e199ebbf530db","msg_signature":"bd29bcdcefcfc9b1c7d9685d5f5e199ebbf530db","timestamp":"1779068161568","nonce":"Jm0fIjMk","encrypt":"HKMqjypyTMjg4e52c3hlHGZWmoFQjOzsBJ0982xacD101Sdo/+6SzwklBfAikf1xktlGdEsrJOTmsqhOTJcthg48WoZhOm0M1R4MrXXc4zmtek9b6vCKvNL5qBD3mJdH2RxvXepoY78pwKSojFZpNiUUOdLvTnIzQLPEngEY29SRpka7yZUHb8liymOJhDrcB5CwFHbYsNdETAb8nUoLJTCGS3bREdJBqnSbTTa7yavj1uXji/82nvTLLqgW+NzpbaNYdj23glp5IwzrsT3IRKCJurEHNMIjh1emDoUJAqsz2wYctYIj+BUpwIZrU9bDEap/hyQmyERiWwT6RvTVu/UTJ+9e7a/n6lR80539MrsU3+kVN5nNQpO9EA7dlynCuTFKTYe2ebuvOdieCQ4OWRH1kL2KKNEUh9Je+jkaYLurGdtduCGuGT95Y58nCFYcaUFxk0hpg1bIu/hqqtH7DCa1JLVMHTM5N//iVzlWcHmxMbhazbaXfV/r5TZAY93BEYtloHeK56tPg4fyqEZKTVNU+r3yGVc3xO6RYecSHm2i5mJvtCYAAxnHAQ6RB3HLyZdX3FsJUqrak7uHCFvchfYNz/BFtU4ILmDgmPYXwniIYbQ76N6eDlnN/ThuMC6r9KjovuyiuBKxfe1CNsGci7fyrvHqGQ0rdwtofTIFYI4Oih9DtEYuLMJ5XhR1eC29FXtUoVRHu8r8Npbb5JEJXKSPne7ZZ7R66QqJ7KWnJs/GunfKmR4WNDyuyzVQy2thcfBlBygdGGVFxlLYCbifIl+M+FqsAu61CrjcfLklFsAFWPZf4nKfmyLy0oGsTJVFLKW9BN8+VEfd5Ayq+9KTPsrDH1bDBfhc2XPdHSzlF7loF8W6EpXUAALjhdZ//Cy7Zv5WYs0Fvk9QGteV/5BA1J2azb+LFp63bI84sUGpdX1T/Z92AvMvLOYc2bWiwPJ5i+2xEzmAXDETCuONSiUczZJi9DEQ5QpdZxp3RJom5KKsquAPksILI25fKnDxWwUg"}
|
||||
2026-05-18 09:36:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"n7TPO9MCSWSMTowwenjDNw08411779068160","eventId":"8d6efa7de0bb4a9daa97a384f8afdfaf","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35/type/start","EventType":"bpms_task_change","businessId":"202605180936000000713","activityName":"质量管理副科长(制程)","actualActionerId":"173760274129324770","agentActionerIds":[],"title":"师敏玲提交的不合格评审单","type":"start","activityId":"53b4_05e1","createTime":1779068161000,"processCode":"PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35","bizCategoryId":"","businessType":"","staffId":"173760274129324770","taskId":101172625123}
|
||||
2026-05-18 09:36:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:36:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:36:01 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068161881, msg_signature=778de7c38b18001fe4d495582d76d2ac1ab26758, encrypt=EGscNi1LyD2n7YTnomPcWIfn2CxzXopH4w9wOWviN1hEX6ZCtFz8RASwX+j88ZOifudgopBsoLvG3YQG4UFJ+g==, nonce=JP1ZfE9o7w0X1p5A}
|
||||
2026-05-18 09:44:48 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"c4da823cee21a607add6bc114b652b929a450405","msg_signature":"c4da823cee21a607add6bc114b652b929a450405","timestamp":"1779068687878","nonce":"mjCyjLDu","encrypt":"mAGrd4oNl/UP5GhVYkyAF2MgbTc+XiebtuiRDW/Hrl1yW84w/GE6IKS/jaEFgPKZ/hdXmdgRhMo6CR0AyDi4yDzU1LkAOGs3GC75z6hQKyXl5qJAU2JLRtCqssGVR44FgV7x8+eX8twOC+8mYpa88rlmGVceNdJEJ3yRUmSIj1eowTM7yFq9by2gZt1ioRw22JLFFUF0Hq+UOR9svXq8K+PEw9Zgq/2aAemB2ILl6FhJLfmyTApkyJcJHSjKUCQ07SLaoBfzqrSW5raeUrDcNQK7BAjMvFI5ARCJ07dU/KlDKezHbH3QJmK7dmIPXl/h96tuzuLo8QTzd+uqL1Qp5hlvDUAMU+OgVxLdGriO9DNfUiAwwgdB+mpKkGBiAJECcN2IgHtfjIkTL+Wes3tlxKoAUgz0lqdFH8Ds0fjfKdFcTcJnCUbEV0K8duR7GrRDrTfxJ4ncGhGVRSPUEvg2zKnrzp8ttz9m/i4s3dgjaHny4vuGXtccNthY2I1A9uajuXmGCnqIT4yzY4z0Wc0uDHQo3XrIZbRHWt38BBkO63Si6CYLFUqGHxElJEFaE5F2pnmrug2bs6bHiz3MItMKjTumLwTRVnLDAxp/z/TatMUNtZrPT854EBNIm8G8u/4Hn7hRzIB+F8/KR5ZWMm0h+B9KB5pEKXtsyjVpMQoED95PogzQMohKO/hOw6orMVrustrhsaYW8j/IZIo8F5mPZe9oBU3Yh+bVI0R6+GVI5MDIDqKfucLh8QRra+a5iovErEDx0SOMKCdRTTGPNmGIawvq1iY82ovNkDPzH6Hn8D5Lf4VWwbYz3PHm0TbsT/cOeLQ61BFkoCMXUJyXtjKOaFqsP+pJIBtHX7CDLJ7VB4YZ6r7lrLZDvsqwnTp434Y1+yjTuM7h17hEeJ+O+bTbBzdNVvNeNAnC2xZwmsMneg3UC7nvQ29PJBoFII3c3Inwx7l9WVF8tmLsY2MzXvUMwpZhEplF8AWEU2Q5hBsIlNEXHz08Icj1TNc/KrQxaD+OyOxoWZZBAgeFN+gEf2i3oKFTdUOD4O1uTmDvG48RMY7XZM1VZXK+XRfhlACpeOk0X3bJHDeVEYdxuRu9GOu0gA=="}
|
||||
2026-05-18 09:44:48 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"xU4uJ-I8TEutJCaj6okI6A08411778812708","eventId":"7b6e4f64cbca410d94af2156460dc4ac","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/comment","EventType":"bpms_task_change","businessId":"202605151038000287274","title":"陶佳毅提交的技术方案申请表","type":"comment","content":"当前技术要求下,杜惠斌和马杰这边无法完成当前宽度下实现客户需求。考虑到方案申请流程的变更,建议将该方案提交给总经办,由领导判定[毕敏霞](02212765235927371076)","createTime":1779068687625,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"231850251526222856"}
|
||||
2026-05-18 09:44:48 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:44:48 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:44:48 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068688212, msg_signature=621c39eef50f73d3ff8f01ae304147bd574c0218, encrypt=iHlTuO6mLziFbh7X7V0+vgIZbeGkGqHoQH55UEukfDRVqVk1XriuExkDCs7qOMMf+hwEDjgZBmmHEpGkDh9x4w==, nonce=7maX9uadzqzhTUdL}
|
||||
2026-05-18 09:46:39 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"f8087ada1ab2b7a81180592eef03ab95b78dd1e7","msg_signature":"f8087ada1ab2b7a81180592eef03ab95b78dd1e7","timestamp":"1779068798717","nonce":"bQUFx6nn","encrypt":"JSJu0D5wY6Gu6I4Hm5JjfytyZbrbQibp5+oaIKtiLDaMf+LsD2Gv7X58G1OUW3RB6iF/OTKUrYibbE6q0fhlEivOTw63aoU+vAKfFZsgEN1B+miC+oz3JsaDWhk+Ra2MWqVjH1jmoHeSAyJ5pMrP9nJWxk0L/dDiSex7uOS8q1zaF5UoXgUErAAZtRBgB1Z3z9UoPaL9aatYob8LUdt56LkWdSW/HDwgCx/2arD5/m6pEdbpIHzeWnoIrUc+OEyZHPqdqSowInPaIysk3ED93uJYOraliSbB7D4kV2bsepFlsZkqMc30msSKcomtNawZwWVrRIdQPMhstdCrffzO2vjYqTiLSW6iJRjIywFT+MnVKdz/Hu4DQ1vNbuB6as6jsbG4f/sTxqDvGGyBn4GpWMVuGNPgK4Gef0JAA7DdE9xNQ5LtX9vvZ58hL1JKjDuRnoAhaCtKtabCyQ8LI+Fm05O99oJywrjrN30lk7mwHWKnZHzdKGQdNFgKzG30r3JivsRIdssWX3ll4ziqNTJxAppz1KQf8dFvy2d5vKoxQHJ5jb5AxuVgsEFJXORbucxI+o7OxgkeqjBg02/FX8bU//tUEUOR96BDOJA2EuX8dWIcn0ey4ULgBgLNACqI0yO9JdiFi5LQeS/Z8uW8hWaRoTwhVrOwwkp0c3fOJD/gp10mi+EhDiWX6jbmg9auhr+pqJEmB8mjinW7BM2o/uePhFFga9QYlmz69Ep+0x1heu+e28o+vb1wVJfAD2dGIJ+MfPH4SnE+vGzFdCGtczS3WnMOHDiehUBtw9+HQyFXFu9X0GtpEioCOlKlbXQRN/c1GewPjixLAv9FKCZ9rZ/mvxdxhXYlWMSyNRpR5ecXCVd+3xtX99kKUeCO6eM2w3z24shnDSDhChVFywAYdfii/Ki9kzmGNWVTok3ZAv6vkoaGn6wt1T/p40ywIa8/qKronU97jQ99Tc7K7suEmHS+xQeE1auJVzTYdCeby3QejLJCNAxMadEaT2wCZmNIQg967QRjMSCnthKoLfKvw91IPRn79iUMSemLyXQPuMYHIFc="}
|
||||
2026-05-18 09:46:39 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"af5ab9d071294855b9c3871995e96385","finishTime":1779068798000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"项目负责人确认时间","remark":"","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"76d0_7eb3","createTime":1778912734000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101190348445}
|
||||
2026-05-18 09:46:39 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:53 [XNIO-1 task-11] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"8d5592b92ab7d881159b10a29fe3c54a8d41f0c4","msg_signature":"8d5592b92ab7d881159b10a29fe3c54a8d41f0c4","timestamp":"1779068811328","nonce":"Q0L14cMI","encrypt":"QHkX41oVsp6QPF96CRR1yRGGEU8Xvn/FCNu1CtneMfBa42Wo+6vLtvZ3ZnkGzy4NUhi26ssmbrlZRWZsXK0PD/kpEawXMogbp79zQeWkyGGO4HnntH8JFdV/K4uz0QqKVxf/1cg37EITwyzuEvoXu5htyRCPYeiBt3ZNjcZj8RrQS9+VUMTY42r6zc0Qt0KPmwO04YtioOwi+XDzLh5kuB3YQ2D0a4UvkfwO173EB4hB/X9mVxBRVPTEPJKDky+BXQQtOAeUc2L2V/+9iJLdESgiY7alLOn6fGtDUbdbqL/w6WuftN0yREYylCTXNfvuPHY29YxLYvbZPcgontLtY2+FjvCda8lXu3olNx6DygXVdHIFC4tRCBmLoM3HjUPs9cdlTXXM0313K6vDp3MxO95Gn1AzFcQ/JZsZ6AB0jfPXXOGS2qdfVwMVISx3btB1csOn6jx3tWyK596M9XYoni1gmLDI+UAvco3CmEv9N0Ljw07AOtCzHOB363f/V0zM/c6IPptL3WtcTi2+5ujdDKEw/GxR2rnZksS0EkMmZv6JnN5yUIx+EM5MlZzd9X8vZqQ8ckuVsdT1XrvGD2UGY6mfaXNIB/fcWi18wEOfppfxjIjqUyxfjNYc+k/T6T5bdNTBUSyyBzw+BSddi+4ImRa3YX3EZnxVffig3D/A2Y41bLpRTiCGWacuXDlj1Vf0DWVfBuAOv8tw5IV8J+8fV1x3GDoaIPjKM7JIJ3WP5pYsUxCY5ILIaxxmh67XwL3LrE+tIVhM8tePjeRMemBJn3w2wZ5MjYG9YCciqnUdmXEr1UNt+hAxajMAk/cRo4INW9hjtUUDdGg4pMIaR17lpFxUFna+YxDV8CxOUP9KQIEK4v3hl50gJnm0m5SgIrr7rZBHkgP8uIRq1wBz15StZ+rtC/CYwvgW8h1+BRZ9WGN6O+Ghaqfj7r5XtDmJpdm90UHlZaKTAhysTIiRX26h39naZLFybl8bXah/aHGBSji00Vsaqs9Xs/Mm5aahsJrMHSpxFyTtsdgZXukPDWbbALRgEeShGx1RfmCGovSrr0s="}
|
||||
2026-05-18 09:47:53 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"4562c86d3a89a93f5ccd23cc1df88c7843da8c0a","msg_signature":"4562c86d3a89a93f5ccd23cc1df88c7843da8c0a","timestamp":"1779068798725","nonce":"fTvamjDl","encrypt":"Y9ZBMp/i7p0RbrAP0aJjXTgy8TfNMxNPExGCmVFG0FkQmbq4nuPQ58V4A3ci8WyLPdnZ+qqDfO+jYDsP55f543G0vZbxtZKpy4bJbQm8k4pKTa5S64d7ZVtsLBmXhrvL1qR1SnLyHf/Ivj9yi7xaQfAi1YsK5ZBQxG7+01CZnBWU7KtLBIZZfKjBLg+QBhjdcrT8MBTbDCjPH8eHV6U6hcPL+Ew5h7y7iowb3SrT0iIkVCPwyn3XSpPJfH7ZG75jKgMkb7up69uPBcJ9VQW+W3/005rnmlGcmbXfpTHmURr7cbywBlWDzS51RY5RUX8oB0eqLmd1YzZw2t5eDYNHbTT85C9CDRy2knVo5kLegvzvikgFXV8ltRxPT9BTGU2YNEhUrXu+vMHErm4PJ0+ZsjDSbiUMdxua27OVsh05uUcxvcivUwmyrGgmXjmJNti34OdAVwNRWrn2zossdb1l9JlNtt/Et3V2nAp6N/5+REpk/6qlpIyCvjydU9FxspAeM4q6nHC60BhiWfn8km/w+q/k5+qEWqflFxV/PKuWSxrRgOUP0B+GQNrQPW4pPdxfZ+o72ISm03l0oUXI+XuE2QYR0W8hstS8O6xlwJmAzbXKGL2IeNEYmb4WanQRVGRUmRqiYW3ACpUHCb/5XH24mOQKFN1LRZB0Yn7dIZARlsPOpTAbNlFkRKlapygysD77idQ0T97OA3bQdykVDcYaw9WWZMgItib5ZsdT5Pn506tc+rNbOviqHr48WwRiOuS+INzbKF7qb19i5ZUmbNZwRZ2qxp3guyqGb5w9gFnFNgsCaZF7yu5OtMjEbHChCquzLHUOdOQ2nitiXg4+GqtktGwZNPGu4VOOr82+tJp08P5tBW3EzrzOkH+23ZQ4euKlq1G8sF19sBjs+oZut9Q3DGEj0qGwZygeUl8SDg9okgfMr65ktWOC83eH1sita8VbKroS2JSd+oH9P6z08kzuaA=="}
|
||||
2026-05-18 09:47:53 [XNIO-1 task-11] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"af5ab9d071294855b9c3871995e96385","finishTime":1779068798000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"项目负责人确认时间","remark":"","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"76d0_7eb3","createTime":1778912734000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101190348445}
|
||||
2026-05-18 09:47:54 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"8babb5e69cad4391a5fb54bb421c57d1","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:47:54 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:54 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:54 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068874421, msg_signature=87ee2a6c56f2b149b3f5434bae4207de8ea36740, encrypt=pJ8f2hb8Zvu8/HJWP/H776+FlNKCjlElpNL6l5645gORrLQvdvQjc/UJgpVQCyZTpzJ2UGQv4HfdSzloph8efw==, nonce=OB1E8k7ffNe1IRWW}
|
||||
2026-05-18 09:47:54 [XNIO-1 task-11] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"815efd81c932c988e2f886f167c693233a1a13e6","msg_signature":"815efd81c932c988e2f886f167c693233a1a13e6","timestamp":"1779068843969","nonce":"NfKtKa29","encrypt":"ETShVBA/eLfP6u8116RcjXVTro6ojyqNLaRugCnpd6PpShVmXZ24O+ShT135b6kCdfyVW1JpcZClpaDevkBgHa+T3n7T4VF1EcTBWVVqLWZYjL982jPoBSig6EdhV9FJjXB3oRu7+42uhdZBnt9cl6YUeaCnKJVXJckdVEN9DZm+w/2wriwVUNcuzAaUB+n19hXQ5mXirl9+KBmq8nbdjCLWpZ5QzMJmPj/79bFllrsC0lNYk9WHeetHxUnR7n2yP4XwEkWt/SSATEImpZgvPP/8dpkcIAgOATLuMkJAbwp2JlGBgCd3lncx491Q6KyTUHoBGm8wym17Ltp5MaTbFXFFqc5nvUahM8OekfruRAYN4gkr//JOGB+vkEJbwgxjq+5br1O0Cf/mMkMiMqBoR/Ope4H6C0vTqAyaChNGIzZRZp8DFw5g22d/+w7g7ZSUUvMMFV3exSN8ok2Cj8yjw8KrWMg7Gv2jNQwGh4vaX3u62NxakXxdtXcXKmCWa5TefCDnnBarHPbox+rkUC40eHmgmkvqmJoJMqbLD1Xrq+hbtSOdJXidU1J8wnYb0DuWRmXFgGG+253oWrmyO6Oy0K/6jqC7RZt7cCfFUjc32O2bNUegpAxM48gtnrtoy+xhkQmIlBLtP/WqWLQNogu3OSGXf43GzqiZpSHxj4jbC7yy9n8/FiRYe/LHd9LAMXBtBhP82mkAz0Xz2E2gs6nYzCjAsAF5c9xQNGczZhFD3tNCMN2oQanap3kT10EI5U7xAFIDCv1yqizYv7ycZQ/ULkGCTuBU8+wcZ1P58eoukBsSXQvDzwx3eaAYEGQjS1le20eFOBHxBquB7qfpE2jFpmzfsrKiNlHD1XGXzWOaeb5U42Er+vsdaaXUz+7TTbsKrmlfKSzm6xtwaoV/1uFXxvQ4GSRKeh6yMNnBs0tlJYCFLO/JOEQ1tncbQ2XTWAEg+JCzQa85m/W73gpyy2yQgEMLPaCJ/L/BOKtK+25Sgdyq498G6ydPfzf7Hjws5PV8WMiU7081HS/Y7Xwn9hlKAyMtoCbjGRqCoGgFdK092VI="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"a488a8a0594d89c01a28cc0425498ea3b34ca516","msg_signature":"a488a8a0594d89c01a28cc0425498ea3b34ca516","timestamp":"1779068847935","nonce":"ovAQwDjn","encrypt":"WLp/z+zJTJ4rlwmbqcj5rUn3q+n9sTPfxfQS3BUxp4uctrzo3OUh6dzasVX4q+3OtVKDjI70D7LPWq2ngoYiBQfhIOxg3aKpCXRiwQ1SRVo6mRmZifch0kowTQST4Z7EYDQS6XT6HNf3orUwRmQw928YDzgkhLBQBKepLh519Dar/AS31qdkqZ/8aZZkx4OLNRn3XL3E0Jfm1Q1JDSpnyPMZdzY4rb+zx7Jw62QVfxJRN/4LHXu8q33QpoeKzOZcrAZ5tah4ThqePidg8giLA0iS+dX6uDqIsViytIpff8zTl11VDFWvRK7ixfEXhRgb6vSNRisedWpgoWyBCNY27qnJmqXEaWSeViSlVrUb3t99ZZLxPe226sukve+F8MbMC3DnbnDZRo4iSim7ioVynOO1ec2g/BSCKJbcyNJ83R9KaKxcc10ECUVWh1Oy68YhlYmdi7ovPKOcoG+AF0rgHVlf2o2Ef2OJbypj9WoYYY/VMTSTJ5WhpIjiBHB1bl4fmpRHu4z+R7wEwGsU6LBvSEEXvHZ5YvwFOOkBtblMo8F6Na8P7ja+ox7lBNV+fU6ee2uiLrtBFrk0QvaB4POirCtBaI+SOOAnpzwfRAALv6iIsI94BzOenUYcabC6KPUbLoaarBmhBNkdjA9YF6rzqvlbLRf05Tnx+lphsYOweL6x0z5xn3LycgmRTNR0ocgALUnrkdl1Tx1SBAzVzzLUXqnLbeYSqGUbSFaVwjnb0af5WOyl82hecwnvvjQBQrWof5xMP0vtz9jFrzdjCqvI00ZVlqriXnW4JHohOyO2u/BhfHv/yqvz3+4BR7h7Pr1zj5F/Z8C3Wgdlf7TZp5PkGNnsxvVUXHt/jz9gReCnxh01Z8ymj0it2riAS6OMazdHiGSEJt+tEqDOWp5xQGGeLe9hF3Jq7DP592dDl6h5OpVA6lDIFBVtSCzTRB5VmiGoecx7/REBfZhqF62w6sT5FSKji1eBvRxGEWGRBwC7R+IT6Hx3hlJXWXcGrRH/ZYRj"}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"2acd0a4a2777fcf0e2d83eabf8ef083dc07d7a24","msg_signature":"2acd0a4a2777fcf0e2d83eabf8ef083dc07d7a24","timestamp":"1779068847843","nonce":"MCTTM4Um","encrypt":"Wvs7hwa9GKXtkOYj6FdmUTh+7k9PU0MdDLPJALm/98XS0/URxOZoH/xPBkZXvI+zBNBO1baE6ESTWVXADNL/XPEw+ctHmdGjMqVIYIuFQ9k4tExVc7Yzex1cSxsF7tahi+PzuE4Va5N5Ewn8fkh0lg8oO2UlTkA28iom/8zauGhwkklju09Wfa7sJymQewH6xK35BKmAGG7w5JEu9t1cXKXwX+12woQ+W8mmDKsbmKpnfm9JKUNm5+6jQ0r5/QNGVLwawh7NDGQu5bE82MgDJSOMp+IGg4pMBhA3ifW8o5B2H5DPRnPHgbv41K6UgsiLrbNXfeejZjk5pG2d4TSqu9TNRMqXdLADPieMTNUlMVY1rSnBCym1NM6jGztHKCEocmlRwztWrytd1glANBwCqMlyH1iqBWk/LcyDuMRibHtSVAxZfxj+BqjzQnDunpUvKgwEStON13Cte9R4ajh0D8IOnd7bkX0IYA8G2HeQ5Kas7+7q3iq7tenq3pDbcjiDBk56xjgMJB2Uhe11NLWp2YpZ/JMkxdZolJtf66v/czlksDsj2v11yeVkIXiu3mRHFowjTAV9X7BYWjgjjr6shpV1CdsntaTIGhacDeR5n8p0w6xuCcHsVgpQKBGZqkUsOWUekaga8DlkXs3fL9v7mrRAlqqWmy6nl+lidsV6wizDYzWTfPtFAkvisDqdHzXd+eG/AoYDPkZq599obHKj8hmyF+sIzDHZ5g7i3cfyZHU9C4rsiRwMoiKrmlP8oJ9ajvHmGRwxdOtdkQxr+sfc6xVCHUT9n2WBe7uOIW6xl8BVcBydiF7LwZmMH4GVQVvSLpjy8bcKkGSnJlxalD5U3boFvQh+2iZT18mFHgxzzen6HnhrErftgbH2lXpqTH/ZGZmwZA18uMiCkh8ZyDdm8cgn+7Hq6H9AJNKTtX7Om4fdCgIrFWAX3DuqPpXGwxhxljcsNjiVJk6ouiHu5s3kOrocq3NWVPdX9rMSYr6jAwa+kaSCQQAUbTc3rwEISTriPDoFa3GAhQ79YyGPT4DTaFQZvCTpX3lNiGNLkRXBuUg="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"92ad2e7f01ed4aa98d0dfa67965f2810","finishTime":1779068847000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-14] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879311, msg_signature=b1dae080bc26798a10f9b2aa10c7e8985f67d890, encrypt=iycm70OlnodzaiVH2Y0w5koJNYkeEGnxRDKWJRwxBK+ONtbEdk14maVz303bYeDujAXrqsKB53IEwx9MZTnDdw==, nonce=jCoXV4B7hdTLUxMp}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"af5ab9d071294855b9c3871995e96385","finishTime":1779068798000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"项目负责人确认时间","remark":"","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"76d0_7eb3","createTime":1778912734000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101190348445}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"18850158dc274c70a2acac8d1f0f32bd","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"264325116326361164","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"264325116326361164","taskId":101105511366}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879313, msg_signature=e38699704788ff586391f37b198ace8b0fbcab49, encrypt=jvMrhLWPtowbaNwc03Xa95lh0zHPOD8dKfL7QArkit89P9FZ7HFY5CtF6Vg9n+HT8zSMMHiI0MerfyX5q8xiKQ==, nonce=MOmG5RersFBI4Nl1}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"10dc47a5ac71099b0ded79da4b80d2fb372f6e36","msg_signature":"10dc47a5ac71099b0ded79da4b80d2fb372f6e36","timestamp":"1779068847945","nonce":"klEtB7a4","encrypt":"heGqm9h/y039L0YB166Ymz0fZEAWesnhBIRZI08NNuMis3+U6GVTTvGODF4RqPL7srLCBJ9t4aBxbaCZXkCQGvo6xHNlcn2lBpLw0debbqSzptmHKjsKK1oGTRvDyr/zwD9z96oc6wh5e5P5SiKjg2oVS5u78iLTFjIFbyC2keI4+yw6+ITSY3PqpibsXIh6SeWujp/MSK7mxhJLRQeEMxJ9mg0tFPmhNDRk80a0ntcuWZD4855Nk2DgKcOuumLSbJgRaybyT0u0jwrIXFzTWZQN38TRQn7/3ivtTj/ZZlvcUYHiPiGsjhpKSv2aYfM6Y/vyDPgnrg4svvPhSlAz67tuHsU+RGrdmMRHp1gBstabrAPtaewYLlJX2foLgg5l4Dbj+5GSnkG1gKWMnr58y5u1DZpM2VD2ybg/pKBLl4A4BM1RAKfxU7+vCE2/6ifW/3ukcQAWto/EuAk6CYqF/AzySEsCdrKgaXM59bxwD9EfrEMSlYuruq+ZWOjUTktdTsw65X6bE9izrX+sQ8IxcQqdhTiOFn00nBdoxSjNglxOgpn8qYzKRCdSfsfyH4NpwJaDn3O6qaj2mfXuyfEaPnX0Z3XxUhRHWT+PspjFPhCG5DlC/5XXhmaDDzVwK3Utsb/MMJCRP3mK4noI5gGs9NZKuje5z9K4Cn9pedB45YPH3MXTI1U/hzzJkbgKqF8/kNb+Pxs8eLrGeSUK3h+JsZr9bveY+ZLoHKuBdVDtEZIN36nKy6C7VRZcwrUNPh2o/5N4Cyt+bzN39qUdPFZOmH1IF2MllLrwCtOew79DLD4FjB2p0CKkMXOqcnJ4/Nf82g8z3vcNLd8D9cFDzd1puN+S481IvWPeG+wHh7mdncefhNfiIrm21a7EVduFzFlgLCR0cbFAJFR9AKod3ovPXHvH6bSiUPJ3EY+dvORnTNmMK9b5nZhmf/kenNdxmElHQZdEccHiL9RNcXPD8Ggov65nmhkXJ8J964fiRJcdEqOyw9mDEqK+WktcQmVDletZ"}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879314, msg_signature=970c2b2f538fd4ccccc16d7809f8e126dba03e31, encrypt=hpTIFRxYV+kshAEytLNvpNMdllXcTAhvL/p7vvnSl1flhAGu5MEL3t3tJT/a/kCm+LmYktqAUc8jn5hwkivJ0Q==, nonce=PhSFYBEVWHGXLsfi}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"6a76bbdef4e54e1d8a3426cb5df1a9c4","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101105511367}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879315, msg_signature=a6bc93d3ef3e7afa9efa13c27ac142a5bd62ac31, encrypt=J/KMVKSeZbfn02/UqnV8UROODdX69r0XNGkWggM0wivBKnMjJwpRYmmqlB+2RFvyTMaogqJv6GVU9v6EiQN25g==, nonce=SJhvVgO0lwyvRtI1}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"ddb4a433add562833cd89453b18f41150c14406e","msg_signature":"ddb4a433add562833cd89453b18f41150c14406e","timestamp":"1779068811329","nonce":"lWop2Q4j","encrypt":"pLu4iTB2j5FsQf23b8By6hnYTqvIDntYPcPXszB7Nu/hR0H5BZOECVMYY4SjYRii7NYl8j0zmMs4PEXhp42vkf4m5l3B70nAL3+nTkuiz6BGSzU0jWen+4a1I433uEyKDp5T48J1uU1liimBMmyXZLC7oSPNJ4dsxCPKLHGHslQ12soOz/oPnrkLMiaNvG6kePqntQ/dfekYnTQq2qCbOUIwI1WTs7NtXiKDg7C9ftFwO1uyVttTrLs1Spq/UHMejDShR1NyV4LY/KZiCBwRZUJMYiUr7V791SMRRmwozQ/U4Q85B1nRXRvclJ/6tY1r8oXJqDmbp3h7x6dfOI5D3NylAWcaJTOWSYklif+VS0SbngutMCxB0Uuiz3Ba1TNposszrEc/I6msCR4xOmbchzMpgfM9z7XeHKw6pLM0AFYYLNE7YHEv3NkICprrEati+CbPg4ZzJmh8SFYVP+AIvEijGQvlhC3JPD0kCx0pF+u2XQUAjZ2OV/eRqrgpkGAyYOmhnUkTXshDPGRmdm1ebFhy10794b1KLLJ/vsnkhouJeM2otlDobMemi4Ik3xgrzLP8O9+GSC5yDs14I4+WaDwU/OEWH3S84Cu8SphKFuSU8CaojAVFKZw1AeA5C/2VAf0tx6ajUQ4J76eFVEDrpSsiGzjQMAaR22j5XfJIlx9rwHoeXHpu/ftzBbo4tRzluwN32dXxSQswJlN4Mez27A5mYyKlp/cyUn+NezzLnDjpqP2e9PstYePh8uP+v1+6/kneCbMYLu0smqQbW4c3riWjxkaNplZqMfuPgQRmz2KkppW3mKhFXwBIWTWuaLKz1pgCFvKqaf33K4z5J87ZWIpmNioas4Oe1GefoFomMIBQlwM0UZrW2qLjcYXsZ+PhryjrzF98zlq6A5n7Ms3ZthHSgTTygV544nxCQ+xiLPCA9/2Tvu+kCzPjufKPDFYpkHY0flSHAlag4pGi7UVhHA=="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"9b482b1878f281f6a6854ba721774bd9cec75801","msg_signature":"9b482b1878f281f6a6854ba721774bd9cec75801","timestamp":"1779068860606","nonce":"IrNXsXsE","encrypt":"Cy98bvaP5TeANpaTznRYxm/XlY84aMiFOEy/FgIUq5Xwr10fG8/MkoCP0gA2Tvgw1O4Z9lPFP1lMa5mZ+gBfwS5Qc6HzMCr//71GBIWxV2PyOq+asrZ4QNESSKKamergcp6ZSQc7JulejfYbYEGHHbV+xKawAkGyIy+R4OVJ9kpv1O8FVBs3+uzLXMOIdUT6hMXB718va3XIruL7kGhYkiKsXFMBCes0TTeOE2+wHi0iCEJS3xS2QVasvddZ7qGcWfURJbcKm4PTIXt1XwJ5QrYU3B+L7OAvnF5yICFwIgFE/cAOd2zQEfVpVb9iBDYA0TILUuNrnyWeywJEvoZLS4/su3VuLoydwwiYCBhVxSiwQ7giuE4gPC47vv8FBtJdSfuAaalSoTYRUeFxXrbAqCIA7GBKkCHiZrUrESsiaYlWRT3nVjYg5u+fmo6gsm4lb3eiF7IlTicLArl5Ifo5y0jSZ7tvu/yaB+s0JPvQOxvJYzcMhjzhziZ22RbdI7LNp+fwquBZbOLnTiSgzhaN2NR2hv2nzoNqniFjMHIYQNj7kkAh3PR0exhyv61tw5EWdpxOca42jMYSHL6hPeUCX5OgcrNt9JIYmXaxNixIorowpB8MosL/Tji0zjTusq5gfIvzypeHtIkMt7dxPEy8vYu5t5KfhMdh/B667ith3pFZbwOdXxvGWDLA0qDm+3BMkE3N9tkzFRNx2c//oVJ2IdE3VlKZULIF1ZOXfJiFTMFOtS6XZvg0PfhV4p4lIkcFXQ2siLMsmZnqReGq2kxr1af5bJnZnATXICK9DTwnUmW+5emt25uIap7Ds0/k8DvDvAbgeyLQkrioVQxFl+9+Nvkl3qnMlZFFPpsuR9nA3mtdc/VCpPv2sngUo5YeEIKxntz+mp0GwLj64TuHQF5ZCr8h9D8+qDP6v8Xa37g71pKoN8V+hXFWUoKk3VfzEwzSgCz0tYpcQxnX5tUpbONqKl2eWETDhs8DTJtxoK4vpt2YZizOpHeCayGXMv/PeV47"}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"b9f10c8f6b648550f92138c1a476bd1638f1cf38","msg_signature":"b9f10c8f6b648550f92138c1a476bd1638f1cf38","timestamp":"1779068860647","nonce":"uBr7MvMS","encrypt":"GYts0SMhvdcGbxmhZu4XhRx0XG3Ix1u7TTLPMkD/L1ZboArXgrBNN7scqFW+iwBtmctdF2VmWuyHAe2HOR8ZQU5yj8T9wiay6SZgxd+TByl0axOW/d2ORlBc3JPlbKlB9eoMICkXAwB3DVJwRPWjDiu5fvWlhFgMNvhK/ztKSZ0mSxmNbppu1wnF0CMjWQ66+/gy0cgG6dsEFhxsJVyI0SnG/p+yimj7+qLTOLFBBNOsjnZCmpupsb4/dpicaha2vskELpmPbeI+DN9ELn98KtbJgAIFcRJ9vo3JpN1DBvoDIjiQJUwiR2RrJrc68B0Ez6f+UCjtxG3WzYsGFOchdq1YzjxXgvhB8G8+7u/OeN5uFW9P1sf3KcTKFlxPXJXax+HzPHpsPyQgpuDfjcZ2c6FSJ9OC2DPeb63ccHB4RpHUhQL3UeBbLll0hWK18xQMqUdZSiVZlhEzEXeiGMb7+xq0MNU49vsLoKIYrpP3ZmR+LVrIaWKUuj45n2JfRxEXePp/EupKqp0Ony1/x8gtdpUXonw687T/nKxB3klryzVocl2NRyDa8u5a7ilfEePZP0bc7QMNaTDtXLYEPrS+pAJMKrOBW+qGe1H3cCdGSIRY5CX3Rg5R6glNqJ8PXvDqR9c5+7EmI9vUNQRebHeTrN0JnrkCUkPJtx0Ftq6dD1rJlyFz48LiMnkyftRuVhFE3CIv3dOMbOCFUXPourzEJJe1h45amvWxuDT26A/T5jJbn5t8fxTBrPn69yaT5NECiWTHkf7YKuZUsPjNlI1QS4njPyCa3ZupDh4L/umELUdBbWBUoRc1Gi+4aSIY7TxXH9K1KFNlUUQ6zevzEteIRy1syZdcZiD9DpbYbztDAbUBMrmW3+0qUU8THwEIX0r3Bentv6o1jftwbCGtxC0D4ZN7LaV1xs0F7DiqKgvGRfLFSV4Bs4lYkxBdPARyfzy+P/+/xTnRoz4oYczFMA5E60tKgINzrMsMSzQsPvy5ksTTleqqnVg8yalHX4krWwUJ"}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"18850158dc274c70a2acac8d1f0f32bd","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"264325116326361164","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"264325116326361164","taskId":101105511366}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"6a76bbdef4e54e1d8a3426cb5df1a9c4","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101105511367}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879333, msg_signature=835da67538b03e61a8b66018038703e516ccf2d9, encrypt=Q1iUA5P1l7pO1E0YYEyCu4cWrNLwOeOZIT/3Tuenw6bIJrNDjzjIrDsDH9Sed/wk4xhFzqcb1SsDroxkW3UZJA==, nonce=3PPMxKvpbxQh2UGM}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879333, msg_signature=63602b1082f47d08bb74556c1a87b265c179cdf5, encrypt=NLVtMm6LCrHAlkIN/ox4FAGBxQcaFSSYYShYqR+drx6eERO7ZoLQfM8JxLOWIFGiZxuNrrMiHyspMrFRSLjC5w==, nonce=DndqMNZK61NXyVYV}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"8babb5e69cad4391a5fb54bb421c57d1","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879335, msg_signature=e44ab598f6d1ff0c2e673fad5f3aee89f330ab47, encrypt=uACE6juJh5x70zGRcXdmjj1qnIxZwxqV6kJq+6RXWObGX27W+ZM0OQDr0iqGLP0qZFQ1sx9LKGjc6EWn9OlhOQ==, nonce=mTBOout6RL3pqjNk}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-13] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-11] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-11] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-11] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879339, msg_signature=9164bc5c6aac92dcc2828186c34c1d04b8213e2a, encrypt=xc9PwRrFpW4GqLOP3Ymn99LytYpoIVtsjRfmZ7kr1Uc5e4qpXC2F7NXpTtVWq+UHTa4KxJWlkx3iCOClPZGCXg==, nonce=R5wvzT1N0iRLzxzt}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"a7a5163074a8ac55fe276234ebbb2f59eeb3fddc","msg_signature":"a7a5163074a8ac55fe276234ebbb2f59eeb3fddc","timestamp":"1779068860545","nonce":"9PQn9Dta","encrypt":"OXymIA1KT391tSfv43vT1wcQ06CiFQQgcGzO9QuVpTDSHivJXZot5SgMc0Trb8NaWIqzBRXydXxNK+bJ5Ey7Higzjc1eBE8ZzQe49CGQfc0hlQRsGQeMcOfRw39sG0EilqIVUAiSfj7XaPSAjznKwGeFhD3BGZl3jBtbcotvYjDvS4K0x8KXZ+fr/+QFVvKenf9uEjwHEltRkCwEjOXTQIDWN7otOCmwpWmcNeBoRU82p4qr4Hb+MMuFWl3eFLBTemyEZOzBSC1OvZki7bdxe8I0H0mOGMZWn00tU6lTH/qizdG7dSGQk0vCeHB/qglQ1Gel4FPYXW2LY/aqj56RHyYR+D+COH9LXu/fBcCe9snSB2zpKzUMm/EZayrXFg/1Ls7ZyexgHcda1HGKe2Pw8WsdKS6owQLaHnsBHJeLpqq/S4XK3MG8vUx7iSsIpmmY84oqt3DgCha2EbMKGeqxKW/ZorYZnxp+lerJTQZnKW7p2lkYBlVm/9acSgPZ+Dqno59Ez9AAnnmiSTY8n3mXxvWYoJuypIMxuRmFa7zas9ypsIGtSmKynIFu1OlYWJZ4FXcX3Sc4ojHF0jvNcsObY3JKxYkA9szmpnZ+jj5liertNcXzVwuVfE0rtK7DcEVQIdNcVKJ0qROUSRX78b6qhpeOd1A3l+Kbwfa5+whdaoVnjj9YMKOv5IfZRsEot/xswho2dg3YtxdccHLX2KnRSdT4Rlwog5FpPuDWSIKX0gXkoorI0jFCLt9hwEfrDhCTQX32hZkNE0Y9yegqxoZefNIPAPxLi96J3ijApz5C5CoQ9oTe0yA8Zp2o9UH4FueFNXU66uiFW+4ih4xrGLM0GcU8A5TbKD2qYnibQUui3+WbOmDxozVAUVDjM5D7hv0CtHTDPLZ5eLYB29EcBaImcuXGp/U0EqAQMnrDmWhQMpAuZgUebOpsTf8IQYTtSvDs0+3QE+kNnQZvlCAY3SdwKydocNNeo+Ryo8Od4vv+1MzbhkpcfO7GdJyn8/qOngkvzr7ljNJiMfG8reJro8xZXAIaXnEILBIJbEvrvR8FRNc="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"92846be5f2d7770afcd2f162c7a3dcd69cdfb4d8","msg_signature":"92846be5f2d7770afcd2f162c7a3dcd69cdfb4d8","timestamp":"1779068843969","nonce":"8GV7r6CF","encrypt":"nDx3ouv9uH/U44g/8mCyWCLBH8wPcTG8gLOfWRQntUaTZrhyNDF2dALbxtF5YCpseQjvRljDXHXEHmrtZKEmxoBE2hStbCCDN7YvcxQ+jxezoETTU3uvdth45Bwv7poOklj/5A1CRVsLA8y2CU06hEDjRDVDnSIfZbiOurTF8y9tyycXPDjZ9kmrebpU5UucpWyezsY+iARTGLCxXCnWjRn4xj68fQPfuCy+0Yy/jKdHB+WKAKYjs0IdJsi5zvZTFBKAkGfTUdfbriw8w+dT3bBaBOAHFtDSsup72SgupCUN4IprU30LzeCRWSiU2kjedp1ksaEQc99p86uEBxIRRuUTmn66zuTwIKeQ9zhr3UBb+DS6F3Dj2DCaWPOngAtf9ZJD4YdvY+EKLEWLrasxD26taGO2KXJ+uaYlLgT6XNnKuhE3a+dOUcpU3t8PCUPOC+Wl6CjFfTYw3mSJwfW7cWxzi5x4cyRxW5xNFuNpNh2Qqvz2xRfJEzyAv0VFEW/sLLKUtSmISMn/8M8cENM8LPNNA5qLej6RhvRNnEz6SAa/feqDONTD5MBV4YDuK2rKMSWsYNCDSMRTrfhWUQF9yolxXzFlky8HEZf5VxXVWiDLoHf92CPNAGDw63AM2ACDvmJs1DQfgRZm/HpeFq9ZXMb20/7ckL8IxZ8o0reRTD+5trleaXiPbQEZcO31+rPT1PkkBz5QoPssamsuskBe8yx6CSH+OzLKEUrvPneZdm3AJv/achLVzhRzj24p9Ch0L2HMjCP9QgUfFAe9g/BbPYWkpLMbAQxcLc5MT01tbsAVs2WpGt4JYszek29X+FhBaMkTzQBnjAC228LKa1OMrbAsoel0kYE0vywfNZB4vhc8kJkmQPT0FrjSme7GNE8SJ6WtKkDMfAJgHwalgCsdhS+XCXw4wnDKEIUs0M1SXWN69RtFhfd/pyf0QlXCus69L9kcZZVMkftFWVsqOwJgVg=="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"92ad2e7f01ed4aa98d0dfa67965f2810","finishTime":1779068847000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-13] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879342, msg_signature=af0ff607c3693c6b10d661e77d781c24541157dc, encrypt=rbskvrjI6WkonSoDsQBmcd0noXABSxrrsMvCyctqBjNDmSU/GpmCl2jmHw8+aiQ6oJDQSgU4P1+b2lkxCFUOTQ==, nonce=vkGkQicHaIUde6Xm}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"4ef219a00b9917375f59c1a2cce5c2e1c4ba8ee1","msg_signature":"4ef219a00b9917375f59c1a2cce5c2e1c4ba8ee1","timestamp":"1779068870052","nonce":"lQQhFVHY","encrypt":"faXOCu/o6E3KZiIH6cYtxH5miuVXBB8Rm/TH12CTB2ag78o/vM7W4eniFc4feorE8J5WdYtazqIzSvfMXHYF6uEsDkw4Eb6KrRSi5a/PZPAQmUlACvciWKNnqxO8DIBQFPnYyk1ayQQjzQldrXlFWMIMNbtRUPhfxmq8QW7LNqP3o+FIky2fpIlLzIf+xXq+e+qGQS96hTKbmnSfImDXatSvE1AIx7b8jYryEpjvuWgq1PN8priWMP9+m5I1Jhvp1zjKov2eP0YpaI7DSMhxfnulYc66upqvvNB1KhGpd0MnME91f4N6WlJKfLjQG2vGWgZh45OYZ79uJwfPG/Ti0GOngTgTBz0swFCzBoQdLhy/BdTbKgWuOgA5mpTtLlBaGfqgfyAK0FJsT7rexGY+Z54Tfk/OqpNszY1NchMwfb/mVx+WkiU3he78BAPn9hxWL68i02Q/xUOQl4VLFKJQW7kw3Sjbuc/44P/4C1qHxNIHev7kfxqwSM2U0fc5BFC9sjdQLZA2TJ8V9cJT/3ZPIlEGYMLRB4+bidR4zvsW21+uvpbH0/F8pIEJNPwKgxVE3C04TtHOeu93n70I3dJ7RDGocBwkWAp4ICUCau/gZQpAvMOTC82a8pOGt2TcTRz2GkR1udB4UyRjCBwEYA7wd46GWfeB/axDtrLje85oYKVsnsjVG/DDDywMPWqAR8CgTtB/xbQyzBsMEMo6FR89dC1MoXVtkkUNS1Zh3jjmIwUzhZoEP9CKrm+VAwLwq4A2EdggAy1NyUaceFUZN9tGOJ/LebJfPyZeYM1NF4Khsu1ebcHYiXUrrRoSaibb81QOXlqJ4SUwEAb7nxZoRYIPfC915WQLYLNIQ5EijPXYYfFswVBN4sk0ruZzxSOx5LRwMENfjD6WVKdgZ+qy/tNAD5ZrHPE9D8hbWSeSRJeQxISStS4ZZ0eJ8LWflRWrXoRHmBuot0O5ZPZ6OVHT0gHUm2vYpqXVuj7z06Bili1+CZ7gNrjI1DktE/UmLKPEj1XJgow/Waw7LNPnYmfXuIUhnhhDvl8WCaFYlbMqh8HVL6I="}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"8babb5e69cad4391a5fb54bb421c57d1","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"-rq9EkhYSqy_p_bPRn446g08411778293593","eventId":"1a0434cd6583443bb6f839346a86182c","finishTime":1779068869000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605091026000330395","activityName":"销售确认收到方案","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"安宏生提交的技术方案申请表","type":"finish","result":"audit","activityId":"f135_c1ff","createTime":1778923843000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101193056701}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879798, msg_signature=033d328f7eacf6b1335567c5207571b3e7e45f86, encrypt=8kYJ5V3RMG/PKCLOLh+8WAfLR47a4+uUPldvgzDgXjikE8IL58/z+IlTIDVokh913TgeEMs1poNT1egpMbx3uQ==, nonce=jvDthhDmIUSWXBbr}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:47:59 [XNIO-1 task-2] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879968, msg_signature=0e0694972cef359a984dd76522dd68c5f38630bb, encrypt=tWc66WGXl/9xLnXvbKeGoRBwBDqXvS38vKGvIKow1TMbgKLJX7EOuTTT/TaT2f+Z4iRxH02DBukb677lfgqhSQ==, nonce=IBRmkZRIAKtNtZPb}
|
||||
2026-05-18 09:47:59 [XNIO-1 task-18] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068879969, msg_signature=a4f4e1a61b8faecaa519cbe4a6d288a5568e72aa, encrypt=dqJomYM7bkW+M/Ex5qoiLMmbj4tMEYhhmClo92pGWuD8/DeccDjyUTJf5ljB8Yjza42umvW9qMLlk7Ggcp8DYg==, nonce=pcSlxryAgsCU4s2E}
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"cc319228350db2dd4083582a8216d7665244c0ca","msg_signature":"cc319228350db2dd4083582a8216d7665244c0ca","timestamp":"1779068882676","nonce":"E2VIJ1aY","encrypt":"dTzQF5wkKWyqTJoMgiqhQVffpiK2CXiVSFn9VZaf1w+aW1Cod6C2v+Ddl8TrvvEdAkhXt6wHmjKUHAU9tnloEd52ig4Zm2hcV389t0ZRm5U/CBSaiTUh5IovBR4z/mxSQeqMW58McZ4+3WQGw0WWBieAOImvbF2yASBuTjptHiWpM0B3OM+B/hG8nZmMHTbmOTG0fNeoUuuBLpwIoRxr+AFdxEVRogCzx+jinlcBZM9vU6iH5JpiCq4yTXD3re0FbytsKj5x0nsse4hRy1U8OTEdc6WxV5ijEP+9qXSYo4KjXby0KWIhLQvRG7OQ8kucucSRGj0eX4+OJTNc+WMUpPpvi8ChO7moXIgbTvFGfFvd7DEnHTYbhLLTmgaVi75cs3wAxnswGZ8xQNs9RRVOggoB/QoJZi3SDbux8qvY73G/S4wMAaVRHCqWN3kACZk6EFpoVHVcH0mxks3dLTpTCm18MFaWFI8f1cnK2rY9M+6qXoc3W1eyDjKa0DhgqBrXqnRdnQLY7MoiTS87tX5FKpULkJJicZfYfEUuQ/kY8wU4/JAYnOI5cWEHVb0h2JslkzclQZRln1s5chrJYYJY3LsSwoXw0oWjKTL0u/Id04QVNbB9+eU2m0KoLJJyZZZuZQN+hG2y5MK57sYl1WvPggbXM54aVv93rY515z7Vzq/QMbjiG5VyO1urN4/r9iRtXYjqnX2iEeqCOPYEX1SkN7L+zLLJ62SZo5odaJ6O2lUf35X3ZQHUSRB+EUSlVt32gv+LRAGi3d9imbhcOU0f+/PKPS/NmY3YvNGK9BhN0BBsRVh74Yop0DPazOJ1ye2bP+vmRzs6uNIVND09V+aCzdauCjAiqJTVByJ1JNcqCdcEtP2A4AA9KfWUSkWKtU9Gpr9e/Pek9PD167/pBwnuWCRpirrPtRwCivDPNdOwzSdcNbAjprU3NBnBqTT/NGIcNMliE6CFz1vfzQuFz1cvIGoi60+Z56bg20dtARiC5lBEw0yE7mkA8/jNNybk/YYV1wN2mNfIBdCm+aCSmY9SuABeUaXeElJziZzlkiZcJmk="}
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"-rq9EkhYSqy_p_bPRn446g08411778293593","eventId":"1a0434cd6583443bb6f839346a86182c","finishTime":1779068869000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605091026000330395","activityName":"销售确认收到方案","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"安宏生提交的技术方案申请表","type":"finish","result":"audit","activityId":"f135_c1ff","createTime":1778923843000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101193056701}
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:48:03 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068883166, msg_signature=7bbbd846cb0055bf823a524f7dca16fb61b20ff5, encrypt=ATnndycsMpVV+6ZkyTNIwaaTKBtnv+VlZxqh/j6S+xBgalgHxxR2BvAVn1SfeP80TNLSBH8RXh2tcFd8U++PwA==, nonce=EoIHJ5LftMMXGdX2}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"9da92f69b07f8e9402292dafbf88a815fd16bd89","msg_signature":"9da92f69b07f8e9402292dafbf88a815fd16bd89","timestamp":"1779068893212","nonce":"oSW8CaTk","encrypt":"IEUoYEbG3T2YZayWdkniPkrcvOGSM8TiNRmJQ4XcNneIu21n6eIqBsiEygusO3UQDSfP2F8mPukNgOqNizxyunaFexFvW6d/G1bW9mAx0JadFDYXw3gL+MYaAqteLv7t2fjmmwgogDncDDm4SS23zND/5e2dtjKwl8vOzcrKpJGgoeKpN46oCMRF/SGdMPoem0iuAdnPJ8zSB6kzp1WLmT5xPCTO2z/fiNfvh3GZxMamh/s1TwJMmRSPU87/bmls/K4J6ShFcSuyc+5c6+MgZemm7kxfgklm3VPlpKX56aXc8kvSz3Cu2nUuI9p1rPa39SNka/dlygBVKeNxKC6BQrKiL/8mHIC3oSTQIptlwuIooCMzMtRKjsSBo5b3KBrBv5JYQBfdJzFFo5Icr7ef7OQbzgiWVadmO9NUUzxY3shMUdEeyOl2dXo4CfhsC4xRMd3AOYSxQM89zzBL8KNAjFNWmSNg02UDiDlbOT+dpQ3zIbu1CUpgc7NMwDsfhRrNJZMjGbe0MwV3XSX8dQvtcxXQT0PjuP5HcRhUFHKh5r5SWNPIVg5UN+Eh9lhjvtJ4ua7az4VrV/Nu3L2dDlxQe2g2tQ9avJdyhj8EwMfxw8aFcOCvS84cxMuH7swHW99JiKLOvbSbFjnWevrCAEE4WGn0k2vQ0jMvkKvmsByxXFQsW7q+JQlSFFs2vPt7VjjWovYP1+cOphkJYACBYHuhIWuvsdYtg7c6Yty8rtj93w7LBEkRT0bhwp3vxBFenrHWnpWwb1LF5PmoMJ3TClnUDbmU16vduS96663945L71mIteRTe7XuHoi0Nv4abq7ryQLuqUUImjWzAhwW8lxoeSUHSHWfyIgB6aPSU51pDL83FIxXnLvtGdTMpheYng8399RRJ6m/QK1o/3HDTyXDe/P0vH2HvfjWv7VK6eLMGOoD/KvG+ryuP3wVFiQBtiWC7RSH76Xao9ssZXIZd2CMQkOnsFUAjjXlLRSqxrMYcCI/a57WkXzHTqpDYE30UBaCT"}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"18850158dc274c70a2acac8d1f0f32bd","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"264325116326361164","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"264325116326361164","taskId":101105511366}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068893525, msg_signature=41b8e9b6ef8a8cd02a504e3e4bfdeb4a827f970d, encrypt=xyvpq+TrrydqN2TbRCLMGjBMukWTnHCuCDb7SBC0TY8FHOgdq7bLjQ8tUeUtZv8pKF3fLWn0sx/HmvGEtxmJMA==, nonce=XzvBzW958Zskpipy}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"2e40ff4cde304e25fac55cd50c19b36fd7b0fd7b","msg_signature":"2e40ff4cde304e25fac55cd50c19b36fd7b0fd7b","timestamp":"1779068893210","nonce":"LNGRmiV1","encrypt":"DGeHEHeIbXnfnQgR1PGjTeedi3I+9DK2EhvdRDx8KqLaDYpNcM48TpCXYp3tsoOld54Wi0ss8ipJl63ZEbS72k5jKTE1K6EK35zPYVotKikPWStOIsxRMZf2y11E8CepzsBNn78bJ6E55HTYc6Z3l2R6ptt8m3/ghUGlWrhBvqc94Y1v72xWduGJWWbLNZY1EnwtwGFRHMXWzgQBCt89h4Q/KdvwJNlCEcnV1DNjDt/Q29BhLilJffo1fxcywg70dLEEppBVQjCAZIvnLvpBNXs4BWud8a7W1A7TAiA/VS1CMXAAeXfKF1gwMMz5OeDxGSYl8RQ3g03+GnLb3mOm7eTusvYQRrZjqSbJcnd7zrgqQqYOQ2xU/bPRuMRlH+AViT+lWai2+vTS5AxY7sVrEjLfmJp9U+gIAwiH7COxUIG1HWjHMb3sHT6j3vbWBcjLOyVDPc0ojRCViv09uEWuaiY+Hr/4ZLO0u5WF4HeOwKOwzq9cJnHL2biFflf3HIO9hzmmgodbDvhGMre9AJ8J5n1cnH+Y8/EfQy2Mvmfc/DxTSiR3SW/AzkMESEL8ahLK/LMSIFdfpAARAsGADyqDNjjepnIzayxvTYXeWgcJpobNM1YRnK8mB0zVLCmImvN5+1Q2hDOtqMC/DUwKtOXgNxqHP0XbzPE8bqz93hRhoQzDc7l/Xx5oaqGca31hxm5msxyhve7I8CMDfFLdOnqMkiMdm5a9yWM02doXGP8aBphFf/A/z/aYvkznV8wDCEJQlZrLVQDed5BqFa92kd8zB6GoVFAI75cn/p0W90y3hAbt3uqE5KMtP13GwkDroI1hbZjkxwF8a7HxJkQCgW6WNeO+N+J9brpnWbjxTRtWbSzlUytn857EElmozefeg0m824ijiEMkrr/USMUSyVuMV0N9cD55JPbsaufS/3MDuRQF8YifijIqq1FRBQ+BrDPZwn9hLWdsHjych4bHvvLWnE998RADKm1jxP1TFlXtxVtQiFvUBAZdxKRM3F1Du3j7vxoIrCVt8RXPBC0LsHYOyCiz7VlOUScXVL38J2pUPEc="}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"92ad2e7f01ed4aa98d0dfa67965f2810","finishTime":1779068847000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"办理人","remark":"","actualActionerId":"03462113426124233873","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"25d1_3948","createTime":1779068798000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"03462113426124233873","taskId":101173037254}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068893547, msg_signature=877c3097e922fa841dce4f2df3872971a195344a, encrypt=i2BezQExsqZUQCAKv17NM66gRJuzOnv4UmOftRyYNoo4KfEOsp0/MeKgwmU/en0phI4u31rTCIjh6Fr8f8PHFw==, nonce=gLL3Dq6EG3bnHnRv}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"ee267417216ce17f014d041a134f41ab81b616b6","msg_signature":"ee267417216ce17f014d041a134f41ab81b616b6","timestamp":"1779068893286","nonce":"wn5KMFZH","encrypt":"blnDbJpd9W2X8Cs1GLDB7tlmKbg178LiWp3fWEDoXWrkJy8eq9VGMOgrU8NVA9G8yES/nFibtSldzFyg6lhlIQ5dUgKXsR8P+cqLAYIqnHj7THKFBuNY3zc/Ln//awWfCFhnmHmeSny9fdQRQl79CKqgp/9x3CnqHAyzwTOoDG4HKrdonnEADHnH6SeNWYuz0mJr6pCwKNQVYQ6MQsoO8csfanPi3N1ACddaV72+tUI2dBWkyd2VhD666M+vNtN09ChU4EDgMczpuqxNLzBitJk9XrADH/Yj9PuhTj5tkDWGTbYuvrnw5oi/qJjG2mQdFV8UR3PyB+lavmXDaqAvZRgakzr6aXT7nn43KxIn8g3ee9ZCw/kzXw/w65ToobCspheayRU2lSebeM4Wh61sAkQ7qfTxQjp7NltCrTIAY2c52l5oSZwrEq4Ctt5Qa0xCtx1AHWIDNdaO0QER/vul7K71jKDEMO3Uy4EFPPNOnRD+QpaibY9stdTyS6XtX5AfJ0W2Xi0Db4kl7nRQwluUGjKE/aI/xSiN9BXDKmvJJFsGAihX1tHFVwrf0dtIYFPgB1k02GnVE2fzgkA1E9kzomnDiFjezgMrHNXo5lRGoveYo39OODSiY+1XQg4PwMwl9ZnJkUI8niyz8FJa/RilM/4YENvo8ycqP2N1qFX0vauq5cAwmws/U9TPHP+sECoFL49mvzw7Uh/O15x0cpnnthmOjoI840MnkCC3iw7Z8hee8BwNzI9Gl6/oVVspo6hBW6f4MwCFqw6LoUO3SynIxGTwTQsHpm8iQw/BDBQANeFubghj/Gejx4pQI4rxk+v0EMD40WKH7I8VoIwljzndxTMNSQPcyOumbZfk2m2QM/aC6DSgzjKnNgp4dibs0Y0s46/czMDt2ZgezKZEJzAb9CRP6pQX/olSKvdx1b/0FgHN1iMcx1tt99Im7hz1qJes5WljsuzSEl96S8XybzNkCmxh+fMSm1J57rH0HuWHz3BuCgiOkJ2zlbG/2lfvfryZ"}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"6a76bbdef4e54e1d8a3426cb5df1a9c4","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101105511367}
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:48:13 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779068893588, msg_signature=9517f1226817288a980237e615e79d2bcf3edf03, encrypt=jvSN88XIM35ozfmfrFAlmzXWgYG7w1GMXO+r2rKVMe5a2qoogojlXQtMSzzI5hTkNsog3N/e8tfbZZ6ECPqyPw==, nonce=Fi5Ws5pRRyzzoUcw}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"25179218391ba785f487706e99da29b4e9db4b4e","msg_signature":"25179218391ba785f487706e99da29b4e9db4b4e","timestamp":"1779069145905","nonce":"lxPyn94u","encrypt":"4A156tExFJvZdD3z4dtotjrOjHpzZWE/xTqkKqLAZ7iOnIdjzCg9FyYgSQceRdpeSWaLWJhtD/2Ldz7MqamhvOq8eIAFQucJjY1DrZqffuguojGPKG5ayzp+63q3Eupf2ztN9/9Vsi9m/XEExk5NLvGeFIc+5kgIzxVcu5jhxCaP+VWudanO2x5DZE26ESuxOXtORu0EGphyY8koV3k8cDupiGfGOYez9rgF2SxGmEJsefZIokn9e9E6XoSQIvnV3P9gwceS1bSqTZdxtrxzPX7pHzYeEUs6jtEoOUoLWljgFE2k6zXd0SIGSB97xQ3JfVFEnUSb2ul9S7xyniLBorskE7fhcanWw7GTHUSkYWjzkw0Vpo/8WjpKEKKP14IG2ScXM1yB638MIDPXGX8XHBU2uWPd0pqc5yDKo2UXAdigMleRSNA9ZDGNkPjU4OoRp1ovdjqGWd6mE7cbVTpM2BW8bAqX3/oSEClEMlTZTiWWaKLjSzHw0/N7/i7Bi3GdP+AuFzWYlJXXz92EkoKNMl9xrh5MkvarJJqkQTaQRtVhhqIiu068quczBtASrXd4qCw+VkRuaXgqGyCgVfgHqA1hICxxBhD7RyEpaXPezwssdMXN9Cbq9S1KvfcES+CPzo9bfSbrYm1U2poJoJkWkDMn9FIsLyX8P6Pa2sg0g1n69Ivl9yhD5y47oVELUesQNLBRR9G9VQFxOcoGq/HcLf2SxU4g1Z2of8WWnDxAjiHqlcjP1YIt9HUACPo6NA9k49JZDKGbH/mTK3Y71bKOOz/30VRrDpPqO77k0HEO6S6tZ3z4N1AFqxLeKBMwcMwKCzIcNnS2vRDFVBJNqp6mi528daktwfz5r9vLrMyCjuI2Px2L/QE3T83dXo5Rahsk2Lm2RHhHALu28exG07wCF3MIQdskzAd087OQoKbxbMViNgOjasK19DP2pxqgPtiPFOP1tRBR1lJznVh+586rUg=="}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"Jhcv53cQTNWexrH7sFpvWw08411778823288","eventId":"12698db62c074352a292f31d9a8ac3ce","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605151334000488937","activityName":"办理人","actualActionerId":"455108492423275705","agentActionerIds":[],"title":"安宏生提交的技术方案申请表","type":"start","activityId":"25d1_3948","createTime":1779069145000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"455108492423275705","taskId":101173181763}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779069146212, msg_signature=4d0d13172fec3030a5f63319c7ccba706cab2cc4, encrypt=Kdoa6JFkh3ADSryXwzybCuuLlwCl8Qcrb/nn/xSv9nn/aAfZBPITugOarg8k0hpJGKLeaH66jDodl4vrHGu6eQ==, nonce=fNfvBf1sUEX5acQw}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"786675c1546f6c74812503b137f2db861c3a9fee","msg_signature":"786675c1546f6c74812503b137f2db861c3a9fee","timestamp":"1779069146111","nonce":"pyvzZ1Ky","encrypt":"CrluvoHAXrnqaSvWJ7Mnd73wchvHLCN2bd5wBTne/WFHXhhA5AohsGtHJdrp+pZxVGc96kM6xBpFGQQN84J9ZNICmz5L+onFJwzmTsz5UOzAO5ccyX3kVQ1EIwBesYQe46B4nEWy6yG84Svnjs9YrWVH62cdrPuNEOX/3/xV5iosIHZRBxHL6l+JPLK+8dFmL26e46Rx0gKncDKvvdEXIgyIncpeo2/9TX9QsKKXE+jqdaCCOrmaz3uYEP9/zlqb1pXVr7RaN69VxpQI4WNVnkDOxIApqwdtMP9h+MLnn9r1s23POSvmuA+NB3c0VuZp/TRECO0MQA78fXe9Cn46lR0AMbInuRJlPUdgjCKbUUjxZoYIyTTsk6fz7fVKMlZenJHwOJMi/J1zwodsgcBvRIjfGvKc923FXPcxq8FOFbIRwa0frv1RsKvi9YNp9FpBlxq8E26rlWRi0tWYQL5W6dItni4gaqhzpL2v8ykD5OdxmynuhqlxQBZUS0YYWd03fZk3Yk5aexuUNsl6YvuGBRQ3I4CHlUuHDd+JXP3uN/1bOODX2cdPb9LloTVq8fMOIAf9cy3qex7MwkWl4MBGCeJw5paNgAwyIQnqMho7TUbxzFHOtNRaUdCCck2YMugJPogz2R76t9ZGdh6UR2CnZ3OlhFHRChN76vDU7yZxfsG9hd3J5EoEiCh0BQh+5Q99w/ANxO96ij41Q71FDB2JYAQati/6A1Cb2vkoFwqQQUEgCi05/hpNhwLVDbL1uY0eeBNCu1Zk3ACNtwPim2KnGU1rxLyUISRIbPq/R5ep1GGQEN8VUsmTfExmjALOwbSrIyPv31Ki5j3SM+NcMEOwtT5XSuugO+YLm9RcszXmRzh5WK2McSUlQaDrVPEVzMcT8q1QY0ohrJL/wIJz2tjoDg4lHKFMvx54pmUQCPJBneOsql8Hxwg80tZGRKws4X1ZD5yO+FVjkKwwQqBnZEnqKS3juptn6u7banKbnUDz9J78vhSAiU0NGr/lCw/697eynL+lJPx4k5qbl0dRSKX447XlOzSQS1PFFJ8XdNJUCCg="}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"Jhcv53cQTNWexrH7sFpvWw08411778823288","eventId":"322d4ec6b97d4e3b803bbf017adea7b6","finishTime":1779069145000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605151334000488937","activityName":"项目负责人确认时间","remark":"","actualActionerId":"283111015435457273","agentActionerIds":[],"title":"安宏生提交的技术方案申请表","type":"finish","result":"audit","activityId":"76d0_7eb3","createTime":1778894788000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"283111015435457273","taskId":101120670752}
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:52:26 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779069146422, msg_signature=d203f73b0634dc374ef221cd5565c314681882cd, encrypt=Z5Xl9KyUhYMLqu8p2AKNFAHXH/twyaRylhnc+uWQCBFcmrGiGSLD3Xp7fZqFKUaZX0hf+7/QhVcLf7GMxEEd6w==, nonce=dS2qordNsKNiKv3C}
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"7b6065b5435ed5dcb845eda206f98891f94b789b","msg_signature":"7b6065b5435ed5dcb845eda206f98891f94b789b","timestamp":"1779069308374","nonce":"qQ0XF5sC","encrypt":"U9/+J4q6Gi/4dQXBugxicM0gvoBr4hT7OqlI2DJ4XI6UUbAocaI3efi8ZTDbhfIh/nG/TpQ6uwP01AXFKXBaoqqKcNXxhx46rI3aoznPspCjhF5Hwag2yjwCa5XAwccYCxipDUfq1SPR1QT5ts/J1w3n8zhG8Jbqx9FgzXxgCHBZc76TzaDeS9zChsumi21WPnU8TkV2mB1RqelwKJnKmiTpn7kKlkrqsNDR3JApcc7gVC2g41srppcVuCEKOJeZVoqyWkBj5YAs2kJ9bfRIgOMzzMvx/L8wfs4NEbWknHj2cdmbQ3lwsRdA6BJiIUBaqFEbV22T63mdPt8XDBVtQiH9pHEeaFw0KNZm+Vb/ahVge0hl5u8lexQMAtwvhOqOiqlz5U3c+CdP57s5LjLfpVJtEAGmKFS3f+ftnzgButvtI5d1TD0XfCHEzVwAKcUe/toCZ/hJqklentuUFeRU34AbkNpRX9sGOqpoF9ofx5ijRSEA9iDTvyYthJfk1y2pdtwqOCKgeqPWRbgx4mWnjzDjZ7yLT6p1ep8dSnoF4srQgwoxTn4AxlqSGhCUgjCrwJyw9HYdxSIeaTP2kQKJS9c/VS2jnMc0TBM8MJQdPr1y6hnAqMjuoWjjHiJ7aOWSgHtLJGSL8K4F2pj/vqhL5PnIZxZBUNDisA+iBYlECKI5vnwskrbZfJ8Lpdpel3yhcA+KIECgdoYGiY7ErGAMVfeZRFirJNH1XHbBUIlVSaYxwXAdsrOtxOuPLT6IgdA355sEnn21UuEu/iAwmhao+mthtYlz5Z2WbsfP9YaVdkGwP0u+rUBfivYCQBjfOZOVz7hPdAMUVHh+G0qO1r/3tTY770CZrDX6Rid9kHH+U44bRgkj7NpzahruphfRIxzD/MySpWr5rPDVVUFAd7WOuNd01DblCbgBT+Ih6/p0rdHbh7VKCfZah27cCfZPpxSdKWAuJEY6JVnmfNZm6o3cRJoKZoBlNbheLtQfWrXzl6RzoJATv07Z5ap2BUvmBxxYru6scFxsmm9/RLo8Xur7f9AXn6UFvCIxSyhur6Rc9MQJgmHZu2Rkkwm1/N0GVQ0E0vrgp5QxpbMToL2J9s7wqw=="}
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"GFB2fmehTxGfA-nBZmMRRg08411778893677","eventId":"1d301848611343f7a0fa54feba9a62a3","finishTime":1779069308000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605160907000570685","activityName":"研发技术人员确认提交方案","remark":"已完成","actualActionerId":"264325116326361164","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"audit","activityId":"ffbb_66b4","createTime":1779068847000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"264325116326361164","taskId":101105511366}
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=audit, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 09:55:08 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779069308676, msg_signature=45d7f40871280721e96497ee0f0796b2cff02706, encrypt=XsWSPFlfpb/LvpWzDvbzmsmPCfMZ6/y1vOnmrqtfDvoYpIukp7rMa2+ubKFEluV6Pls4Mw0UNFHdNm2JpyzKBQ==, nonce=mLxoJamn3JSUc7GH}
|
||||
2026-05-18 10:09:39 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"965dbca5686125f011000e7d7ca26e3fe7222778","msg_signature":"965dbca5686125f011000e7d7ca26e3fe7222778","timestamp":"1779070178915","nonce":"I5T7Dxbm","encrypt":"zeP3BErVMQM5HDkXap/1r2ZdobBIhMSl3bRB7PfZt1aTTsiU7VPThvWR45EwP+uOq4O8eDqp4/63VcfM6DM3CdWZFwFG869+kbyiMLnkE9kV6ZH6IiSA/j+AacKCN44hyPswFFxeP4wgYvRo5Dtcym5NX5Mobzy0XF324Ri242bc7Im7mCgKfn/XQ/FInde4w1UAD7aZprck0+LB7LQo61P/3emuKg7li2HpjdC4wogcwqujgGpOZcv/scxP68i4k1YMjhjOInDiAITWUJxEkbWUSBTCiGeaQWu5u7jj+bEomxDu6jNHzTN6GrIUA2l7yNaZvVsL0b1juqSf6HDbbEAN5BB4DAnwH9wuSsVS2RcbsPqyxYdVgmFFrVAizGdefP220T/1DFdKJBp9lc35wvfZChEk+LAxklrVVY3weUcZegWJzD0eWOcuwk+SA+zXRdISRfO3V/PQQ5SsDU5DLlchq4hm2PrF5z0JXm93Jpem6EOCjMEjlF9YVbTOh4HNY2Lm6R3AJRGW13JH+TcaRqNd8+93FjMGsNaI2+LP9vkE104eh50bd0G/YzSlAm+yvuYrL1fgV0/d7/Aqp9CU27jD80u+lajc895mM7hFm44lXKd6sX6+s9fu9HpFZ+P1RXbWFeZZxB28pPwcVoNHteXpO/3PK7xUtu+xg3b9MUYxT3ysC372ViZCoX7NYkhscwyjaHEf9xJ9VoCVhIP9dsG3AbXZVVeRcSYm5zCO7wyaa5fQZrCdVW6jeLI+yroDsMmRIubMyi16DEC+J09Ek6b+uYZQ4xksy1V5aTl1QuEQoYGQT/wW7a1t+O2ndRGHuFpxmXUBzyKytfRMAwWHIbAvG7onAh9I0EoShoCtMIO8z+T5d3RX4Cs4mVoGWeZ+ZqUHoTIBjFnwlrkOlsGYABIwhfAmampZiLjI2yR63zXY8Xb7cRTf9/DxLwvhwgC9Iv+w1v8LAdADWzawr3EqxbcUGO2DgXSLw61M0OlB7MLyNIIzT2l0ICFqU2oXSMTk"}
|
||||
2026-05-18 10:09:39 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"gyHkreTpRr-PZcWjpVBJYw08411779070177","eventId":"24c3fc1f79dc4285b099ddf84c8d7f97","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35/type/start","EventType":"bpms_task_change","businessId":"202605181009000376823","activityName":"质量管理副科长(制程)","actualActionerId":"173760274129324770","agentActionerIds":[],"title":"师敏玲提交的不合格评审单","type":"start","activityId":"53b4_05e1","createTime":1779070178000,"processCode":"PROC-3E5AA98A-55E9-47B3-BA84-0D2101BB1C35","bizCategoryId":"","businessType":"","staffId":"173760274129324770","taskId":101211684920}
|
||||
2026-05-18 10:09:39 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:09:39 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:09:39 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779070179216, msg_signature=fd3343e2473f727c5ab39ca4ceb33ffaff852217, encrypt=2XQSICoX9e6eZr8/qNW1iNqjxjSkhET3jovDtFbG43Oy52SDGCbJb44GzdY9LIrbpKnO7XxL7+bOvzvz9689Dw==, nonce=BNTW8F9ds7mAHDtc}
|
||||
2026-05-18 10:40:09 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"2b1174ab86e6d89902f08e11e5b0cb8a7d271f2a","msg_signature":"2b1174ab86e6d89902f08e11e5b0cb8a7d271f2a","timestamp":"1779072008955","nonce":"WdIFCUiu","encrypt":"eM4tJfTaCN1u3AZgcE2qBK4Leg6qcCB4sXkzSGogz2fqD6DTxZrKLgGtatBjMObmNA05HtjojEZWKE2rEzVk1vQtotGMkNU3duHl0m/9oz+6sJOlWsCGsFb2CQvn1Aw+02SYCg9tlxGqvui/+Ir2ts18d+ZL59Nj+7JpE6KDVhK2rsTiqX8+zCVU0m9NT+L3xHWr3hFIliRAjey0VLwQNsi0p/l6OD5Qvcmn6OpigbubCnydfkQWzmR+hWpAFBl0VoeaE8Gn3uclFfuF8sQzygfUj/BDxZEYmWPXLzWBX4eNp5grBNGO/U6WVaT3I16/5KnHWhNP6uQG+L+fP0rP4AvA9htL6g1VW5Uq2D1I7fVSnQU8gA1+LDRr+UjEQXlX4xr808R6aPGw9MnNojbKjxh3nmjduHd4Lun/ZENRQXGXK1JR5W06+ddBB5QhNWZ4N++mbK4T5NwpE7DJrzZ/aDp8J0bk+uNoh9sYC4215L+3r3FHwHYcz6p/2F5NhXIJHTIKsMuorgV6rrN/r78CLGBt/ujb8PRd3tFkKJSDORw8MaLj7xJKGH7f0QR1EQ+QogGzBUOTTByM8DEWtYqNcj33wH0KE364YDb1Zff8hX4cQOkn7OY5CGlyCczR9MzPYVKNosHCh2oV0Z3YmVnBIz9IoQIfDoqpB8bgw9p5VN2ed6h6cqEcCY646t+kCf+0ZQVngYPIYk8ibnM+tYYD8kLvT79YViueMDwpdlVrJMz892Niu7ESNOwnW5mqW2Mp+ipoLcsU9k4xPu51ms+10L8it66daseOTgfS44KN+uS/F/Kr7UhVig+qjaoLzn5osG00cW+E/7nb4FFjFu0tVmA/HhcIkpBx7bxRvKpkV4cYSCYnFjsXgNdCk/6VxUd4btAAPzvZa8tSpccZlgMVudynSH79xqtVY/Eii3YmSc/xqwj0Ab9Jt5tOpak1iRl+Q1+WiWAkwG7Iuxg1IleBSgTnklZ0Q1cSpr4c8hpv/AUZxe1m1Ygjh88cQ3Opi6u8"}
|
||||
2026-05-18 10:40:09 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"d072651a182b4e0283b24e5094b72e69","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/comment","EventType":"bpms_task_change","businessId":"202605161455000597391","title":"位晓峰提交的售后联络单","type":"comment","content":"售后时间:18-24日,物料预计18日发货,21日或22日到达,经核算,需三人才能保证及时并提前完成[南正一](223241230721375124)","createTime":1779072008698,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"03490008103620345098"}
|
||||
2026-05-18 10:40:09 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:40:09 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:40:09 [XNIO-1 task-8] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072009247, msg_signature=ad08f1965e2f6d709e7e06a3025ad2b91db13a25, encrypt=fQL73O2qKXLdpV6nMmwJrjvLlKsXc4XikopiRXqWTHibn74z6KSVgWTTeKD8PmZmlDdeRJUQdqFgBwXio9O7mQ==, nonce=6kmxMOCgtb8EcRVu}
|
||||
2026-05-18 10:47:04 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"039568052a399c041a8c264e4e1007fe3300759b","msg_signature":"039568052a399c041a8c264e4e1007fe3300759b","timestamp":"1779072424161","nonce":"Hpc1jzjm","encrypt":"LXYx8WVBTEIqmUB3nCq/D3tbvTY69KhF+wxS/6i6rN/R0suZCmLJGVCCPe94e39bGC9e/l5102BdORauuR/zVrS/+4IWt6YuBJwQSJ7FBpANrYemFxcFptthHRRxjpc3ivuuyx00dLNR1N/sJguRL27whqcAHmSmpU2omlKyDWfHYIHMiXkFyJuQNksXPliBpEeJdtmW3LAlenJ/XyEyGWhoDpbZ3AB+zVbHq/1TjhP1DdvEVRn3vj5WQYKp2eugnFN5gabhFXcaToYW1nU98AshCcrIG85OWQ8LTlUUSsKYvPlKGz4c9cuQLc6o++5o9+nadLwWHmlXUvOhAuCuqNLTx2WvGFYX664TsnZMfD2go9NgHtq3S704hjHOcluSOqbMgSqiSGSpQ+/VqhmWt2ZfUI5WXdlOAMw/fIQidVFNmBM4sbE3QmXBUtPk95U1JyhOdKeZvUMWE6Qrcbe5frYbcaxlmxpqiTUxp1Nin2lLRJgE3Kv2szvPvdzYtT1pVuqUT+G0ae0KL0KZQFa6Lfg3RSiq4PD3p4OWGbewVdViQVaGPt3ZXKb6zfcdc33LPCspyfBYGpLzfDpCXC73nCvLEj29ZbOytjl0KPDo0ErjZ7VNmdM3S3yoA3/VvmGrf7t+YbJmtpYcRWbrIpcTPatwh2zKm6LPRW3hug5gK2ANAaC1PAf0Dllez1zNVsQQGzEQjIel8HjAEPR69i28nwesQf5rcRS7nzHV+khdO47onFl7NA4lJ3N86+4dLlVQlejieDbV0u1ZRR5ao+i/V6h5BRAXo86ICS0B3NUTQqOPpSfqTJ5QS9zpoyhQ/HVY+CBGJz75pdn8h2q/jmhOGZDVtMbqo24fhTxRnd/D2CR6VGg5C0T2/7HTBXCzkw44NfZkdSH6ZhHAb8Cl8Z6IjlB0TRG0Z7m6AJ2jQE1OsWusdqMi/D9iH/CxydvJ5d4n1oxGnMwH0md9VEOem0WvqpSrurv627yqkezDWn2+eXdFVU0mNJwdj+tugQuQQVIqfg9zw6QkOL2QIh2YiztRylgQSbkN3QtfsZNszNIgeg8="}
|
||||
2026-05-18 10:47:04 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"f79915287a4c429d88d02f8e6c0bc0dd","finishTime":1779072423000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"总工程师","remark":"","actualActionerId":"035715651324258877","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"agree","activityId":"122b_b71f","createTime":1779065245000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"035715651324258877","taskId":101170493283}
|
||||
2026-05-18 10:47:04 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:47:04 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:47:04 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072424451, msg_signature=86cfdc6167b03664c4380b7187bcd3fee4e9aa85, encrypt=mUOnjTBJtHoM1WfCWej4kMtiY20m47Bl7hNBKy2/ZQxIvt56N+a+6TMwhQyMD1fgnMxFVrfYciCfp34wCBr2Cw==, nonce=W6jGEgHRyaRGbpx0}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"eeb7c32d823b229e7998617308fb2e88af50923f","msg_signature":"eeb7c32d823b229e7998617308fb2e88af50923f","timestamp":"1779072424228","nonce":"C9b2wnjY","encrypt":"F42kI2JXEwNvg2cTSys92Jx3N2Y8bmd4+QIrhY2FOONA50K+rW0RluehXdZjukKYfQAZdgxEERovFkjCEJdqrHA8JhTBj/piCyQvdYsmUUyy7JwHqlptY98EyaUHhFL7Ucmp2dWPOM4+d+JImonRMC/SPBTK5XFjJ7l+c+uqUBxhEXWGztRtYQ4UkhmNzDhz+iiSzf/wCnyEQfGRrR30JFV7havBsQsbUBMPvz2mOc7D4y6uxt59OZbdkPCuygr9zRjC7ayyKA70zw0WfCIlNxPRq0ULo6rHVNp290rN4mUfOsmylNy4vvzXFV5hQN7bi3Ba3K0ON4SyPdMML1z4ox+2/VqUt2253J/VEgvBO7mR5YvFrbfSXIJtfcBiLv4u7DcmoTjJMUJrzSOFkll41DAjhO9LqnMmWpGOEOQ1O4bOsgy+M3h95NsFaPPElnU+2nKOBQCv7b4tjvJ8Lzr/MP3woHU8AWYgzztopqZJDDOriwX4mfZhMBxye43vR4B8p/qY+VW2V1QGKug6X+Wa0grffZmSIyXIRVfZryQhA7mZNmoV+N7xA3hHB4jk97qmFsy6doH/lhTOiD4w7HkC0PBCpsEuWYMDbQZRoUeC71xrOSAGevZmyI8jWkqhCg81sCPX5JtqIcQC5bEa5rfzarlhX3lclqky7NxGAUu3ZKBon3Qon+0FrlWvLPD4q24rHvzdmPRZntaa/pqOeq/hc9qSYWuvd//cnylsSR2Qgz1aFjy7SfRBG2wRIWa9ltRwWuhJ8+Ts7/BY+wLdrF9b9uFiM0lVl2lzvMEKXXBDrG3XzGt0vH0/gXWGrWycbnA4/I4uDuir9e58X601DZv5dDPbGpRT7/OE08/oNYR2vmLqJBrMODv6PgSoBYEOpbkBttDvQNkD4j78l90DO/rTQBZaO2u+NVHbcAkr2mDZ8uUbdODbTG3QWvnV6gceJEmyax0FbEbWDvyGsF8pQL+iEWIVxjRTvUYxW0JzeKUHECC5tIgpb2/BHHCYqQAYqudZ"}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"6e7ab2b133884cd7b613be7f8747f55e","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"项目负责副总工程师派工","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"7246_df51","createTime":1779072423000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101175493981}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-16] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"a29ba660a5912ec8567359ecd6e95b2e4cc9a5e8","msg_signature":"a29ba660a5912ec8567359ecd6e95b2e4cc9a5e8","timestamp":"1779072436820","nonce":"6e9KSNxD","encrypt":"+lAEGFFus+FDzLAOYJO+xHgNQ8yxR43xcttAhDJFUOzv2vDcfDUWz3FRK/FgTjq3tBf3P3RpS8mg+D2eWfB4mkDPgUqIJaYyshK46uBX2O5yL6TH4Pf1ZrWE1LI9yRi5QT860jwXMgAVHvzDBvizBz4OY6+oZsv/C13IecTEKr+CUZZ3aWOyqlz4OrfbJ3VXWi2n6yYh3LN2dFUm9aUfc293LsuRR8x5IC5caxrRceZbE/P7J3HsbgWWQpEdJfOVULu6mT/QFLkx2Kn71iJZlvTGi7+7HOipSJpWv5y/RhWiTOVh8XEVoQD2giwtXrXc7wUujJTweOjr3hyUgk3pdIjdAn3w/Dh8RkIYHsA9Duw8OqLG907BwbnCRPF4lv2/x/r+HXAT3aHWIlrqqk8poSWc6CscnE1jV/AG0UUTmDswpYikdYSywPnOlZlK9/iTR2JGSfE8Si7OSJDNnRXvPrONvR00TUEVPVEYv8IZxHUG+LzeT/XZREpLtjgQzgP5KPwwT0X4jKAsW4MfexOv60r4rnt+AT0AMdxUcX1zB+t0z2z4ad7AwIli/CvFZdEsqJMeGpuwpBWAqFEEuT3Y/aBFNdXbicpEPdBwe1KaHmFE8pBeKOCvKYYiVPsZSyyEqvqp63kkd//wG2xufEEsP4EabJ2Vk/dgRPOLg99w4Rd0Qwpo0Ahpdvwd5c2Ay/wYfrI261V4bUAuZiKwNberVStSn/mb1VYr8eu0VMdpPyY/Zpdeo8QORMgjoapSWQAJ8TH/d9/y0VZmrHg8lNZdLga8kXcIrkNrA+Ym6pf4C3G4K5+pUaEwUjAJ2bLpw5s6mjB9LEHky9wjUoFunb76wPRB9c+o0NqJ7snwF0oddVp0TMBLhguz76YfVkx1GUaBnilHWHCSJdQNzTxcD24qafZIzEcMoV9o9EDiY+lqb1lgvlG86E8Mx6lvVFvI6o48EuwyKMlxlyyZasdF+63TfSaJFN8zOS9ULb5+O1L/O7RFczMcxL+mP04ORg7axC5L"}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-16] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"6e7ab2b133884cd7b613be7f8747f55e","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"项目负责副总工程师派工","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"7246_df51","createTime":1779072423000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101175493981}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-4] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072477001, msg_signature=9d26ba871da9dabca346d38253edc572d6fa61f5, encrypt=x7mIJywRw/ngmVo6ZUQQfEalHp2ZI/sGNT958CvPKLtqZEMxolBXu8hyLfVrn+XknAJ1X2SBvW8C6JDej70FyQ==, nonce=rSFr3mf5w2hEsilh}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-16] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-16] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-16] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072477004, msg_signature=3679d65403927114872dc198a19de821c6b63a44, encrypt=mplUAgNW5Ypd4BPmMHs++zS79FQH73PHGcdkP+QyjhnehQhApoBK1p6nsbWU24wf4POSG9zrIBCQu6fxj/F5BQ==, nonce=Q3SUriR7sxn1ql1B}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"47df19e37999aaec94ed34848ac53f5ad490c11f","msg_signature":"47df19e37999aaec94ed34848ac53f5ad490c11f","timestamp":"1779072469464","nonce":"G4mkvtTI","encrypt":"RD0jOh2vQOu5Z1qsYeaMQX1s8agA51l69RzsMmeGXTHyQCFWht4DSXGgbN/XxsRit5o+UpBR/9M2iAl7Kahyh8Iv6VSrBl4yRyyivopnR10ykvooGFzCzvAL43JQsGshYDSiJnAJVb93JFscYoShRuViEExuFyMOZp4qOYjnSfwsTBD02ZBjVwXpjlZdzZogiHNsdSNdLhhH2E1ziIhLeWATDFdeDmThk0OjAJP7wooE88jQ6yqBzclzKFuSwuM4G0L5rwYfFY6pJ07vBt3vxZ4nv9Avhsupir6b3rHl3ePLgRfSHAPGbreJC0n0Fm+jiGMvS9dQcB8MYDHW9E3K+JbetePDSAZMmkvV+nyWM52sTOqyJf+iVlpz2QNllFrsQDjQMVjCYmBtscRL1bYGSnzJSYdRNu4podxqkdtTfOpIPMBJ0TABfyprrTeYUypD0v22zs/HayNJ1Ha+UPuHwuDzQ7FffNmnP9sTH/truxaft5EO/GTti5o3INwbr4u+O4eJZknqbzUFmma4qbuYusd77FmoGx1E/es8mx4dAtdMiOqkHRTW9QvRFt6FBnkLPikMvxNw7U0prlCuF/DVabz5PQyxVvLo/E2uc3M9JDT+KOUFuoJeGU5PM01MGjyEIZID6f81t5pRBbk44SEI4oTp2MTkDdi2DLuXgGPKhSO7Oq9USjdgA07GUJfochqJDWU3q9A3PouW/GfmOoxFRfsfY5LhOsq+PaN0ac/U5m3doBONBT32hM0PxDdQGCXtKVxFvRBF2Y0vk5fD9P531h+gddv3agXG1n8y3mDF4Mf/hSy8JSaJQ4O+Kzf8FoRtfg2G3QQEJrX9/zDTOgG5ACDnrqvvP9QLkw/PlI4m24dD4DbFGpCqG/nZF5ggDSRmPnaCMrSEFeR3/mI0qu2882Ri3PkkCGiv1EUkkBu2M8tjfnbaVW6VP6xdEpB6HSmnll0nWPGFEYAIlinDz6ZAnbPcZY7uFqlpFH+Alu4hO2/XEhuE5sl7XCzXJde3Z8rD"}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"6e7ab2b133884cd7b613be7f8747f55e","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"项目负责副总工程师派工","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"7246_df51","createTime":1779072423000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101175493981}
|
||||
2026-05-18 10:47:57 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:47:57 [XNIO-1 task-5] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072477005, msg_signature=fab0463ce6ac2c0e87ff2f42b75beb3aab0d2098, encrypt=NTMuvy5ex6Ffp+4AG7hJu8xCcJtM8WHf25nZbyqxNMsCIYdUsQ0vRLrzApjWt1ltKEd8OFufWw13mult1BZ5XQ==, nonce=IAAAFL9pL1VgrDfy}
|
||||
2026-05-18 10:47:57 [scheme-bpms-HHIC0OoBT8OYiZJ4jnAMmQ08411778917283] INFO c.r.c.d.token.AccessTokenManager - 钉钉AccessToken刷新成功,过期时间: 1779079577593
|
||||
2026-05-18 10:47:57 [scheme-bpms-HHIC0OoBT8OYiZJ4jnAMmQ08411778917283] INFO com.aliyun.tea.TeaModel - [com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponseBody.success] There are some cast events happening. expect: java.lang.String, but: java.lang.Boolean, value: true.
|
||||
2026-05-18 10:47:57 [scheme-bpms-HHIC0OoBT8OYiZJ4jnAMmQ08411778917283] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 【方案申请表】审批详情已拉取 trigger=bpms_task_change processInstanceId=HHIC0OoBT8OYiZJ4jnAMmQ08411778917283 title=张新怡提交的技术方案申请表 instanceResult=agree status=RUNNING fields={}
|
||||
2026-05-18 10:47:58 [scheme-bpms-HHIC0OoBT8OYiZJ4jnAMmQ08411778917283] INFO c.r.s.s.i.DingSchemeApplicationApprovedSinkImpl - 新增钉钉方案申请表归档 processInstanceId=HHIC0OoBT8OYiZJ4jnAMmQ08411778917283 id=6
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"b4879f86c32754af3be1d8121ff6efd33f45b731","msg_signature":"b4879f86c32754af3be1d8121ff6efd33f45b731","timestamp":"1779072479827","nonce":"SvxWbj3Z","encrypt":"UpmWAJD6Dnshiwcz2hd/ALFDhdfscNwwOwxS9b2sF+Z3EZ273cWyh11oCV6LuXLduXdYgfpf/8DPKOn036eAhCRTSnolfEpZjp/5hc2Np2Qf+iGJI+b9W4ZsK+cgCIrYPBfb5XCGLfpmlqVVsM5QD/zORum294+2vXs9LxFclhKtM8cNTwd9eE7XCVxWBfMqu8vg7UK2QdSvaDrA1O3BKfUoxZ8Evjvlzmzi0xZVMUYD+D4cZJbyPxsk5LQrETCpVWX+i1IIXNiktzsIU6wBQfnC8uRW6gSV6ugS/1eE5if9YVkFoQzszeCe3hTX1oPO64w/FuY6EZ/VqItBz6WZbjKSqeN9GUeZZM1W/tjjmCAlNNBLfdnvaV7NzdrNdJrF6S/b8JOFr0Qr494aaGtv7zFH3kbiQN7rYU2yDEf6oGW16XMfvSCjN0XltxtBK+GJiEKSeNiEzer0eW/IF8MQloKgGhUN5hgBLt1KQ5zYya1yuil4MAZ9g3krFenkbT8dKyGRUJEqPPu93FcwNDDub2bUoRghPetWLxhFIxN2fZYaX6y1PoCCh3fXU5CHTpZiLBQOH6kku5zDcIktdUFUFhzhNI7FaIamFsjBRlEIyvo2ADGfckbCO/4xpxu/suwi0kx2TUTAG0zbYewQ46LtIPU4QSMYgsCHiJ98IF1B1nWW8ZLBA8kTRDcwzZcxT8Jr2AGrKOyc3Hte2+e0HBxfaEtToVpLwU4ymtZzfAH82yOEzCT6MkU/IhF5Q2lAIyYcu0MucZwBS4irqBP7twRxqyz+z/t0pMaI0HWXEYhzZJNu/tsMq+VZfqKKEPQiTyktbmV9eH463C86MEUpfyb1ldPlEk90xXjtL1SvaiqpXz7T66iAfxi2rr0USoeRf8f+CeQYmve2xRp0g2RbLBVjriOKw3aIWyydNtjjO5KbwsS5gix17VP/SzikKPOaH8nPYOaTB9gTP5n7MbQ79y4Bzp4oVVLXm0jGdp2hz1xzIX5p9JL/MHqakXbNpNlKhGtE3ORS4X0N/taO3vT0DF5vs5f+57YL8X5dbQUOaziuBh0="}
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"f95721059e21456da5a1cd2510dd927e","finishTime":1779072479000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/finish","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"项目负责副总工程师派工","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"finish","result":"redirect","activityId":"7246_df51","createTime":1779072423000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101175493981}
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.c.d.w.SchemeApplicationBpmsEventHandler - 跳过方案申请表 BPMS:eventType=bpms_task_change, type=finish, eventResult=redirect, onInstance=true, onTask=false(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072480140, msg_signature=e201bd66f7d54ac900bfd42e06ba1746f271cc0c, encrypt=7lj7arY1T/FhusUG/hJcNbOxrZA6Ry2DQRQubwo4vQ0o817yM2VigrGahZm75oTAy7r8rEaNBceVp62OOdYmLw==, nonce=c0iepBkJRLOi08Po}
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"37ea659760217291c0eef264658d5145d238c85d","msg_signature":"37ea659760217291c0eef264658d5145d238c85d","timestamp":"1779072479869","nonce":"XbCfkFmp","encrypt":"A3tq2oKKJSnQfgUC/mKfNJQWG+EzpNb5QdRCMCQ8rqlF0B1YVd0TL1lguU/XX/XkzvCF3vbKkRPr+0IG+MZjA0t8ZRsXXT7i4YoYRseOu27zP2CqHZnZLrJuDBLyD51X0o+ClMBnD8UDXNyXlIDLXuANWzW3P2V0Hq0nsb34E0rvw2/NEEq47FcvpDI5D3rl0pdfIJb8ffK0DWhxaoduL5IaZXw0qQCuL7TFcO1HbChtcfqdq4OyxS0cTG07ILi6FHX+fk3sHbgDTbF+NR97W6fvlgEIgzfjPuvAEzdqfqCqqwmePkD9ZvmdQ7Ltpe4S4ixCehGfh0/Qfx0x0Ubx2eEIyfyMFk67faxubJ+Pqd3T0FkqdGzUHunjIlXp6f4O8pqg0lwHidZXVTkmHPUZLVw6pnnHvjPGPPge9cFh1czfWLFjRFILQcL5YpzJ0d9G5/a2hv6rx2I/ZxfmiICcrKljfRDP8/DVnBN6cXKRn027CpBurgy7B4Q3A9XcJem2m8+Px1tPStqO09gy3mq+NU33cIcd2SpESj6GNzydsfvzzoosZMx3HlOKf5po9gjzrMcAurdQVaSkk1PAwq05UTjcHJQwBiHWQmx7K58IZT74ctBBeIyeJs4U8bm4mR9TuGP4+r6PaLcY9XgfX/ooNZyZKUVLSD3Cshcx/IAQg4LLRRTFIWPnBXl798Jjudw0vAxVHN22n+13UYPeOtvGi80DXSUK/7fpJFW6n6h7lult9U8jNecJC9JRDJfWe4ZL7k/GzJ1saAs+vyyE6p5iTMdII5XssOLLLOD4kiUG08x84duDpCBW5JrH6LqIjIxxRBpha48m5jVyBo1yY5RxMhgvOSuVCW6cZ1htQ8MFSTXfoDyVIEWM7oLbKlS7Pxl85NMhyKMTAQHdjEwXg/rY8wF7Ww1NWmacERVShOHUaCnAU6pZaxsJ7umhB1C7fLOaOseRy48fzJbPqDOcwANDF5W67RB/FJnYR9JJwupc6gKL/S+stWno0cMAD2PZLiAJ"}
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"HHIC0OoBT8OYiZJ4jnAMmQ08411778917283","eventId":"8068023167d148ec8b93e42df795cc3b","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB/type/start","EventType":"bpms_task_change","businessId":"202605161541000233493","activityName":"项目负责副总工程师派工","actualActionerId":"0412414241844204","agentActionerIds":[],"title":"张新怡提交的技术方案申请表","type":"start","activityId":"7246_df51","createTime":1779072479000,"processCode":"PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB","bizCategoryId":"","businessType":"","staffId":"0412414241844204","taskId":101147114901}
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:48:00 [XNIO-1 task-9] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072480213, msg_signature=9d95cd76654784eb9308c22f6442efed55fb893a, encrypt=HShl6bg6ogXnuIANspiwCPBRBHmP97qpPUW4Lc/7j4xMp8BXybKzdUsi/qL84RU8h4joMlTtKdg8JWd/19zqEA==, nonce=lVpWTKUuRKeypkyv}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"9790c119cd1af61c5140b32bdbdff2c0907630ea","msg_signature":"9790c119cd1af61c5140b32bdbdff2c0907630ea","timestamp":"1779072518957","nonce":"oaR80ue9","encrypt":"i9M08Xh8DYvohsuMcpmlHVm4HdbAdgPCBOlx9/XbMJmVB63Gjkc4GjfnhivP5F9EwZeM7Wq5uu35cuFgjp+fWg18gYgkdr3oxWZp0KRXQ2muIzgku/7YoEXVt6V7f1q8T0sLoTj/VHD+0M6mWoJa6ARqRczzhCRFzT/++YzMhLtwcdekJKmWCk09yw1bVVUBcpK1n4PSX+SkUJnDwhk/+TDCSx0WqUfIjZbCY6RRWwjetZvcpksihwZPrQXkPaU3XGaleXmMHULpZmeSay8TTiXmkcnpx2hLGoRURQwbtg/ZedOCw7CnBXQvr/y7/57t8I+kFk3YwcsKJMGHSOVthBNcAZCRee0gnc1CGI4vwHYz7jw05SFRUItaVJmXPz+3NiOElzpsDxUn9/W/sIEBmEP18ScJ9pOJSrlbLrdz60byOOV1tGk7HYRRV2TsJL6Bu/bOGEEwIR9MLXl74QzQ+W7+JI7FNBMSlKaijP2Q4xsqkuXmpgO51Je9K2tnJjTO97on2S5Z4N1H48b93MplKsvasAzVP64by1Y955MfVyVD4aVa+roooUZDAFHFswUnXoCBBDWxXIndmiO105b5laIM7FnEUVDjFrElwCZigqvN10l8Usl/DAvK1RJJsdgYm9oZwqtWU3IxfUWaKry9o9AJKkb40U+LEDAl7C5iyxPgu+3gjPl8pGt2FdLmxOHctSEsXBotPt0/QAI9sSd/uPiwfsp/3JdYtZFiQ+eWBH2z2w73EQYb0Q6Psk1/wZlr+QRcyugju38H9aWz3R586PqgZ2KUfp7Pwt6+0+T83i5Nxgy89YHwAsnY1Em9JyOFOQX68RB1vXc2aN48PUWwPNjIVSTgjRIV7KMwjZngZTJVgVcD8tvRgxBvRXQz0v7SmVzxb+thxcQuc+8Zw7zYGk2mqveKSRfimrcB3wagRvSWJC23MIGjxQwnCa1ChvVOR/qIbPJVdugUUs/sGCJ7w+QEEAzliLKpMoYPxZiKn0xXYEzLVeq0IamhhlVGwxNht9K0TTHcYCQWDeY3apDckR9zBSlQSnW7mCQgUuOBUm4="}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"e961172ae36e4c8aba3dfcb339984e5e","finishTime":1779072518000,"corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/finish","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"副总工程师(非标)","actualActionerId":"3816683726197864","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"finish","result":"redirect","activityId":"d81a_b76e","createTime":1779068038000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"3816683726197864","taskId":101144070875}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072519243, msg_signature=cc097f6a822236f3901d016486f3e10ae1849c6b, encrypt=2LOYOMDdqcyGM6ekYXQD6Kjrsd+VQHwoB/6M1pt2NOZ6CAlBFF0bKTBEvQYN4dbiKMZEPflRsbo9sr4WW/qNqg==, nonce=H8OFqwwk0TptTMNu}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 收到钉钉回调:json={"signature":"b2082f8ab72b407e2a2c00bac95d2abd6c174344","msg_signature":"b2082f8ab72b407e2a2c00bac95d2abd6c174344","timestamp":"1779072519189","nonce":"IZKeY2uQ","encrypt":"XvYWIAbcuIs+m87pWALkAFUOpOEzVt/A1P1cvZRofepQp/JnhxlLuzZSbVYq3IVxpZ+ilzIC2eBwD0XM97ujl+cZ1xEFVffP4QMxTKFxmivucEN3MrlyeGZb7kY4qWO05y+B2vXKFF4SCCl5ZenvbnDBEOoZu38R+ovh+OTItKWSojTJtVtPw1HendbugPfAv5MExOwJbu9dAVpGNPGUBseVthG+BZqOZ66MVQwxVrxPHmq4iqHCZ9IW7od34ffvwKjcckJtP6bshMRgiFArJBMr2uhLSQldUP7S3s4usqvHjdkf+bYVMMQ9HfpkallFunVR+PMlG1f2nawwWh7YtOClDyUBLjoMYKCFkcPGnOptVEr2dHtY3zJH/uaaiX6X4od9VHBs6Wqc3qE1NxwSEgDAJ0V6AJdKD//9VkJzGxtT94Vb0LMoxPhWzkWtrkLoT87f6j2V41gozUG2EIUBeZELYyzhbszShmXLSDBFBmQgDR4DuJmZ27WvVP0wFmogN+QZ+tOocacAQy8+QICr4Zj1xqHsgbGRidV0IM+dKO0hPj4iw5jco44FY4M9Wme457HFM2zA7wK2lIhJH6WYKueOki3vd+on0jK9xg1LsnM6dRrU4gtBiZr2uZBvLHgX+z3X4ditFqQOmgnUJh5ze2E/qcD3OS+d/RJWAEjAed4WQo/8+DtsvJdmwfBHsjO5OUMjfgw6kPhoxgCwoLlKcDNUFjCLUjzxQ+iWk/taFWhxEps8t2DY1eB9zBJocvrq1mR5Ji3+5elkzMMh1iQnLG7YV+olXDD/8o9xSrLkS1efPVHLIEMyvFnFYW3Zl84qZoSrOVMF0Wsk4OwzQIGCZdHrI1J87oLvX50Vngwy/aLewk6LOXPH7x76lIOxjLGgxBXZsgHqvcXyVqE4Oc6RkwxWPOaCv5h0KOBiaASfxJ3LCM8TmyGtx6/U6hkpYHz0lhhlG9jQXIJ0yZkd+6/Obg=="}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 解密后的回调内容: {"processInstanceId":"RywCD4-WSe6yxrpgQl1YGg08411778914559","eventId":"b7eb7ffcaa794311bf0ff842cd95e40a","corpId":"dinga5c6eeb2f797ecdbf5bf40eda33b7ba0","resource":"/v1.0/event/bpms_task_change/processCode/PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5/type/start","EventType":"bpms_task_change","businessId":"202605161455000597391","activityName":"副总工程师(非标)","actualActionerId":"231850251526222856","agentActionerIds":[],"title":"位晓峰提交的售后联络单","type":"start","activityId":"d81a_b76e","createTime":1779072518000,"processCode":"PROC-A59BAFBA-8AAC-4943-B4DA-3FC964AC47D5","bizCategoryId":"","businessType":"","staffId":"231850251526222856","taskId":101213660295}
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 事件类型: bpms_task_change
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 收到事件: type=bpms_task_change
|
||||
2026-05-18 10:48:39 [XNIO-1 task-19] INFO c.r.w.c.dingtalk.CallbackController - 返回加密成功响应: {timeStamp=1779072519501, msg_signature=1b1fa612dc9a6c14bd9acb057fe2d5ce3f1b36cf, encrypt=aG84HF3dTVjHH9D6/2gQpaj2BfKnHEYJLD12xvtFjLC76dZoyim16ayaGVmxACy1Cdu0UdM672+itE5o+AZSzg==, nonce=nDwSG9UKcobJYhIu}
|
||||
@ -99,14 +99,6 @@
|
||||
<artifactId>ruoyi-oss</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>6.4.0.jre8</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dingtalk</artifactId>
|
||||
@ -161,18 +153,6 @@
|
||||
<version>1.39.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>1.39.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>1.39.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
|
||||
@ -16,11 +16,14 @@ import com.ruoyi.system.mapper.ProcessOrderProMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -34,7 +37,6 @@ public class CallbackController {
|
||||
private static final String TOKEN = "VDAhP9mGgALfgWioUHlVr8";
|
||||
private static final String ENCODING_AES_KEY = "p9QQoHGCX1wiwSkHnLiPhcfymUCOmNum0CBuYQfFSiu";
|
||||
private static final String APP_KEY = "dingebfrpzqko25vo8w6"; // Client ID
|
||||
private static final String SAFETY_STOCK_ROBOT_CODE = "dingwoaeaozawfochwoo";
|
||||
private final Logger bizLogger = LoggerFactory.getLogger(getClass());
|
||||
@Autowired
|
||||
private ProcessOrderProMapper processOrderProMapper;
|
||||
@ -53,72 +55,250 @@ public class CallbackController {
|
||||
@Autowired
|
||||
private SchemeApplicationBpmsEventHandler schemeApplicationBpmsEventHandler;
|
||||
|
||||
/**
|
||||
* 钉钉事件回调。勿用 {@code @RequestBody}:encrypt 为 Base64 密文,整段 body 按 UTF-8 解析 JSON 会失败。
|
||||
*/
|
||||
@PostMapping("/receive")
|
||||
public Map<String, String> callBack(@RequestBody(required = false) Map<String, Object> json) {
|
||||
|
||||
System.out.println("【CallbackController】参数: " + JSON.toJSONString(json));
|
||||
|
||||
public Map<String, String> callBack(HttpServletRequest request) {
|
||||
try {
|
||||
bizLogger.info("收到钉钉回调:json={}", JSON.toJSONString(json));
|
||||
byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
|
||||
String bodyText = decodeCallbackBody(bodyBytes);
|
||||
|
||||
JSONObject json = parseCallbackJson(bodyText);
|
||||
DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(TOKEN, ENCODING_AES_KEY, APP_KEY);
|
||||
|
||||
// 检查是加密模式还是明文模式
|
||||
if (json.containsKey("encrypt")) {
|
||||
String encryptMsg = (String) json.get("encrypt");
|
||||
String encryptMsg = firstNonBlank(json.getString("encrypt"), request.getParameter("encrypt"));
|
||||
if (encryptMsg != null && !encryptMsg.isEmpty()) {
|
||||
String msgSignature = firstNonBlank(
|
||||
request.getParameter("msg_signature"),
|
||||
request.getParameter("signature"),
|
||||
json.getString("msg_signature"),
|
||||
json.getString("signature"));
|
||||
String timeStamp = firstNonBlank(
|
||||
request.getParameter("timestamp"),
|
||||
request.getParameter("timeStamp"),
|
||||
json.getString("timestamp"),
|
||||
json.getString("timeStamp"));
|
||||
String nonce = firstNonBlank(request.getParameter("nonce"), json.getString("nonce"));
|
||||
|
||||
String msgSignature1 = json.get("msg_signature").toString();
|
||||
String timeStamp1 = json.get("timestamp").toString();
|
||||
String nonce1 = json.get("nonce").toString();
|
||||
|
||||
// 1. 解密
|
||||
String decryptMsg = callbackCrypto.getDecryptMsg(msgSignature1, timeStamp1, nonce1, encryptMsg);
|
||||
bizLogger.info("解密后的回调内容: {}", decryptMsg);
|
||||
byte[] plainUtf8 = callbackCrypto.getDecryptPlainUtf8(msgSignature, timeStamp, nonce, encryptMsg);
|
||||
String decryptMsg = new String(plainUtf8, StandardCharsets.UTF_8);
|
||||
|
||||
JSONObject eventJson = JSON.parseObject(decryptMsg);
|
||||
processEvent(eventJson);
|
||||
|
||||
// 3.返回加密 success
|
||||
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
|
||||
bizLogger.info("返回加密成功响应: {}", successMap);
|
||||
return successMap;
|
||||
} else {
|
||||
// 明文模式
|
||||
bizLogger.info("收到明文消息,直接处理");
|
||||
JSONObject eventJson = new JSONObject(json);
|
||||
processEvent(eventJson);
|
||||
|
||||
// 返回简单成功响应
|
||||
Map<String, String> result = new java.util.HashMap<>();
|
||||
result.put("message", "success");
|
||||
return result;
|
||||
return callbackCrypto.getEncryptedMap("success");
|
||||
}
|
||||
|
||||
processEvent(json);
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("message", "success");
|
||||
return result;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
bizLogger.error("回调处理异常", e);
|
||||
// 返回错误信息以便调试
|
||||
Map<String, String> errorMap = new java.util.HashMap<>();
|
||||
Map<String, String> errorMap = new HashMap<>();
|
||||
errorMap.put("error", e.getMessage());
|
||||
return errorMap;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProcessOrderProStatus(String outTrackId, Long status) {
|
||||
private static JSONObject parseCallbackJson(String bodyText) {
|
||||
if (bodyText == null || bodyText.isEmpty()) {
|
||||
return new JSONObject();
|
||||
}
|
||||
String trimmed = bodyText.trim();
|
||||
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
||||
return JSON.parseObject(trimmed);
|
||||
}
|
||||
JSONObject wrap = new JSONObject();
|
||||
wrap.put("encrypt", trimmed);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码回调 body:明文机器人消息多为 UTF-8 或 GBK;加密模式外层仅 ASCII+Base64,UTF-8 失败时用 ISO-8859-1 保字节。
|
||||
*/
|
||||
private static String decodeCallbackBody(byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
return "";
|
||||
}
|
||||
int start = 0;
|
||||
if (bytes.length >= 3 && (bytes[0] & 0xFF) == 0xEF && (bytes[1] & 0xFF) == 0xBB && (bytes[2] & 0xFF) == 0xBF) {
|
||||
start = 3;
|
||||
}
|
||||
byte[] payload = java.util.Arrays.copyOfRange(bytes, start, bytes.length);
|
||||
|
||||
String utf8 = new String(payload, StandardCharsets.UTF_8).trim();
|
||||
if (!utf8.startsWith("{")) {
|
||||
return new String(payload, StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
JSONObject utf8Json;
|
||||
try {
|
||||
utf8Json = JSON.parseObject(utf8);
|
||||
} catch (Exception e) {
|
||||
String gbkOnFail = new String(payload, Charset.forName("GBK")).trim();
|
||||
if (gbkOnFail.startsWith("{")) {
|
||||
try {
|
||||
JSON.parseObject(gbkOnFail);
|
||||
return gbkOnFail;
|
||||
} catch (Exception ignored) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
return new String(payload, StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
if (utf8Json.containsKey("encrypt")) {
|
||||
return utf8;
|
||||
}
|
||||
String gbk = new String(payload, Charset.forName("GBK")).trim();
|
||||
try {
|
||||
JSONObject gbkJson = JSON.parseObject(gbk);
|
||||
if (hasChineseInRobotPayload(gbkJson) && !hasChineseInRobotPayload(utf8Json)) {
|
||||
return gbk;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// keep utf8
|
||||
}
|
||||
return utf8;
|
||||
}
|
||||
|
||||
private static boolean hasChineseInRobotPayload(JSONObject json) {
|
||||
if (json == null) {
|
||||
return false;
|
||||
}
|
||||
if (containsCjk(json.getString("senderNick"))) {
|
||||
return true;
|
||||
}
|
||||
if (containsCjk(json.getString("conversationTitle"))) {
|
||||
return true;
|
||||
}
|
||||
JSONObject text = json.getJSONObject("text");
|
||||
if (text != null && containsCjk(text.getString("content"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean containsCjk(String s) {
|
||||
if (s == null || s.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c >= '\u4e00' && c <= '\u9fff') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String extractRobotText(JSONObject eventJson) {
|
||||
if (eventJson == null || !eventJson.containsKey("text")) {
|
||||
return null;
|
||||
}
|
||||
JSONObject text = eventJson.getJSONObject("text");
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
String content = normalizeRobotText(text.getString("content"));
|
||||
if (content == null) {
|
||||
return null;
|
||||
}
|
||||
return content.replaceFirst("^@[^\\s]+\\s*", "").trim();
|
||||
}
|
||||
|
||||
private static String normalizeRobotText(String content) {
|
||||
if (content == null) {
|
||||
return null;
|
||||
}
|
||||
content = content.trim();
|
||||
if (containsCjk(content)) {
|
||||
return content;
|
||||
}
|
||||
String gbk = recoverGbkFromLatin1Misread(content);
|
||||
if (gbk != null && containsCjk(gbk)) {
|
||||
return gbk;
|
||||
}
|
||||
String utf8 = recoverUtf8FromLatin1Misread(content);
|
||||
if (utf8 != null && containsCjk(utf8)) {
|
||||
return utf8;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private static boolean textContains(String text, String keyword) {
|
||||
if (text == null || keyword == null || keyword.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String normalized = normalizeRobotText(text);
|
||||
if (normalized != null && normalized.contains(keyword)) {
|
||||
return true;
|
||||
}
|
||||
return text.contains(keyword);
|
||||
}
|
||||
|
||||
/** GBK 字节被误按 ISO-8859-1 解码时:°²È«¿â´æ → 安全库存 */
|
||||
private static String recoverGbkFromLatin1Misread(String garbled) {
|
||||
if (garbled == null || garbled.isEmpty()) {
|
||||
return garbled;
|
||||
}
|
||||
try {
|
||||
String fixed = new String(garbled.getBytes(StandardCharsets.ISO_8859_1), Charset.forName("GBK"));
|
||||
return fixed.contains("\uFFFD") ? garbled : fixed;
|
||||
} catch (Exception e) {
|
||||
return garbled;
|
||||
}
|
||||
}
|
||||
|
||||
/** UTF-8 被误按 Latin-1 解码时的乱码修复 */
|
||||
private static String recoverUtf8FromLatin1Misread(String garbled) {
|
||||
if (garbled == null || garbled.isEmpty()) {
|
||||
return garbled;
|
||||
}
|
||||
try {
|
||||
String utf8 = new String(garbled.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
|
||||
return utf8.contains("\uFFFD") ? garbled : utf8;
|
||||
} catch (Exception e) {
|
||||
return garbled;
|
||||
}
|
||||
}
|
||||
|
||||
private static String firstNonBlank(String... values) {
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
for (String v : values) {
|
||||
if (v != null && !v.trim().isEmpty()) {
|
||||
return v.trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新工艺审核结果。
|
||||
*
|
||||
* @param outTrackId 审核卡片 id
|
||||
* @param routeStatus 工艺审核:1已审核 / 2已拒绝
|
||||
* @param bomStatus 项目状态:8工艺审核完成 / 9工艺审核拒绝
|
||||
*/
|
||||
private void updateProcessOrderProStatus(String outTrackId, Long routeStatus, Long bomStatus) {
|
||||
try {
|
||||
// 根据 notificationCardId 查询
|
||||
ProcessOrderPro order = processOrderProMapper.selectOne(new LambdaQueryWrapper<ProcessOrderPro>().eq(ProcessOrderPro::getAuditCardId, outTrackId));
|
||||
if (order != null) {
|
||||
ProcessOrderPro update = new ProcessOrderPro();
|
||||
update.setId(order.getId());
|
||||
update.setRouteStatus(status);
|
||||
update.setBomStatus(8L);
|
||||
update.setRouteStatus(routeStatus);
|
||||
update.setBomStatus(bomStatus);
|
||||
update.setUpdateBy("DingDing");
|
||||
processOrderProMapper.updateById(update);
|
||||
bizLogger.info("更新 ProcessOrderPro 状态成功: id={}, status={}", order.getId(), status);
|
||||
bizLogger.info("更新 ProcessOrderPro 状态成功: id={}, routeStatus={}, bomStatus={}",
|
||||
order.getId(), routeStatus, bomStatus);
|
||||
|
||||
// 如果审核通过(假设 status 为 1L 表示通过),给配置的人发消息
|
||||
if (status != null && status == 1L) {
|
||||
// 审核通过:通知可上传金蝶
|
||||
if (routeStatus != null && routeStatus == 1L) {
|
||||
sendAuditCompleteNotification(order);
|
||||
}
|
||||
} else {
|
||||
@ -196,12 +376,12 @@ public class CallbackController {
|
||||
// 根据 action 更新状态
|
||||
if ("agree".equals(action)) {
|
||||
cardDataMap.put("status", "agree");
|
||||
// 更新数据库状态
|
||||
updateProcessOrderProStatus(outTrackId, 1L); // 1 通过
|
||||
// routeStatus=1 已审核,bomStatus=8 工艺审核完成
|
||||
updateProcessOrderProStatus(outTrackId, 1L, 8L);
|
||||
} else if ("reject".equals(action)) {
|
||||
cardDataMap.put("status", "reject");
|
||||
// 更新数据库状态
|
||||
updateProcessOrderProStatus(outTrackId, 2L); // 0 未通过
|
||||
// routeStatus=2 已拒绝,bomStatus=9 工艺审核拒绝
|
||||
updateProcessOrderProStatus(outTrackId, 2L, 9L);
|
||||
}
|
||||
|
||||
// 调用 DingUtil 更新卡片
|
||||
@ -219,28 +399,23 @@ public class CallbackController {
|
||||
if (eventType == null && eventJson.containsKey("msgId")) {
|
||||
eventType = "robot_message";
|
||||
}
|
||||
bizLogger.info("事件类型: {}", eventType);
|
||||
//只处理「技术方案表」且「同意」场景
|
||||
schemeApplicationBpmsEventHandler.handleEventPayload(eventType, eventJson.toJSONString());
|
||||
// 4. 根据EventType分类处理
|
||||
if ("check_url".equals(eventType)) {
|
||||
bizLogger.info("测试回调url的正确性");
|
||||
} else if ("user_add_org".equals(eventType)) {
|
||||
bizLogger.info("发生了:" + eventType + "事件");
|
||||
} else if ("bpms_instance_change".equals(eventType)) {
|
||||
// 处理审批实例状态变更(钉钉OA审批)
|
||||
bizLogger.info("收到审批状态变更事件: {}", eventJson.toJSONString());
|
||||
} else {
|
||||
// 其他事件(包括机器人消息)
|
||||
bizLogger.info("收到事件: type={}", eventType);
|
||||
if (eventJson.containsKey("text")) {
|
||||
String content = eventJson.getJSONObject("text").getString("content");
|
||||
bizLogger.info("机器人收到文本消息: {}", content);
|
||||
// 4. 根据EventType分类处理(审批/URL校验等不打 INFO,避免刷屏)
|
||||
if ("check_url".equals(eventType) || "user_add_org".equals(eventType)
|
||||
|| "bpms_instance_change".equals(eventType) || "bpms_task_change".equals(eventType)) {
|
||||
return;
|
||||
}
|
||||
// 其他事件(包括机器人消息)
|
||||
if (eventJson.containsKey("text")) {
|
||||
String content = extractRobotText(eventJson);
|
||||
bizLogger.info("机器人收到文本消息: content={} conversationTitle={} robotCode={}",
|
||||
content, eventJson.getString("conversationTitle"), eventJson.getString("robotCode"));
|
||||
|
||||
boolean isHandled = false;
|
||||
|
||||
// 如果内容包含 "你好",则回复 "你好"
|
||||
if (content != null && content.trim().contains("你好")) {
|
||||
if (textContains(content, "你好")) {
|
||||
isHandled = true;
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
// 获取发送者ID,如果为空则使用默认ID
|
||||
@ -255,18 +430,16 @@ public class CallbackController {
|
||||
String targetAppSecret = dingTalkProperties.getAppSecret();
|
||||
|
||||
// 如果是安全库存机器人
|
||||
if (SAFETY_STOCK_ROBOT_CODE.equals(incomingRobotCode) || (dingTalkProperties.getSafetyStockAppKey() != null && dingTalkProperties.getSafetyStockAppKey().equals(incomingRobotCode))) {
|
||||
if (dingTalkProperties.getSafetyStockRobotCode().equals(incomingRobotCode) || (dingTalkProperties.getSafetyStockAppKey() != null && dingTalkProperties.getSafetyStockAppKey().equals(incomingRobotCode))) {
|
||||
// 使用安全库存机器人的配置
|
||||
targetAppKey = dingTalkProperties.getSafetyStockAppKey();
|
||||
targetAppSecret = dingTalkProperties.getSafetyStockAppSecret();
|
||||
// 兜底:如果配置为空,使用常量
|
||||
if (targetAppKey == null || targetAppKey.isEmpty()) {
|
||||
targetAppKey = SAFETY_STOCK_ROBOT_CODE;
|
||||
targetAppKey = dingTalkProperties.getSafetyStockRobotCode();
|
||||
}
|
||||
}
|
||||
|
||||
String accessToken = DingUtil.getAccessToken(targetAppKey, targetAppSecret);
|
||||
|
||||
// 统一使用企业机器人发送群消息 (不再使用 Webhook)
|
||||
// 构造回复内容,尝试 @ 用户
|
||||
String replyContent = "你好 @" + senderId;
|
||||
@ -281,7 +454,7 @@ public class CallbackController {
|
||||
}
|
||||
|
||||
// 如果内容包含 "安全库存",则调用 KingdeeWorkCenterDataController 发送安全库存
|
||||
if (content != null && content.contains("安全库存")) {
|
||||
if (textContains(content, "安全库存")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
@ -290,7 +463,7 @@ public class CallbackController {
|
||||
// 异步调用以避免阻塞回调
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendKuCunData(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendKuCunData(conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
bizLogger.info("已触发发送安全库存");
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发安全库存发送失败", e);
|
||||
@ -299,14 +472,14 @@ public class CallbackController {
|
||||
}
|
||||
|
||||
// 延期
|
||||
if (content != null && content.contains("延期")) {
|
||||
if (textContains(content, "延期")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendMassageDelayDate(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendMassageDelayDate(conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发延期发送失败", e);
|
||||
}
|
||||
@ -314,14 +487,14 @@ public class CallbackController {
|
||||
}
|
||||
|
||||
// 预警
|
||||
if (content != null && content.contains("预警")) {
|
||||
if (textContains(content, "预警")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendMassageForMultipleWorkCenters(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendMassageForMultipleWorkCenters(conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发预警发送失败", e);
|
||||
}
|
||||
@ -329,44 +502,96 @@ public class CallbackController {
|
||||
}
|
||||
|
||||
// 采购 或 采购申请
|
||||
if (content != null && (content.contains("采购") || content.contains("采购申请"))) {
|
||||
if (textContains(content, "采购") || textContains(content, "采购申请")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendPurchaseOrder2(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendPurchaseOrder2(conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发采购发送失败", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 工序汇报 或 未入库
|
||||
if (content != null && (content.contains("工序汇报") || content.contains("未入库"))) {
|
||||
// 工序汇报未质检
|
||||
if (textContains(content, "汇报未质检")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendProductionOrder(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendProcessReportNotInspected(
|
||||
conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发未入库发送失败", e);
|
||||
bizLogger.error("触发汇报未质检发送失败", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 质检未入库
|
||||
if (textContains(content, "质检未入库")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendProcessReportNotStockedIn(
|
||||
conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发质检未入库发送失败", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 已转入未转出 / 转入但部分转出
|
||||
if (textContains(content, "已转入未转出") || textContains(content, "转入但部分转出")
|
||||
|| textContains(content, "转入未转出") || textContains(content, "部分转出")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null;
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendMassageTransInPendingOut(
|
||||
conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
bizLogger.info("已触发已转入未转出/部分转出数据发送");
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发已转入未转出数据发送失败", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 开工未转入
|
||||
if (textContains(content, "开工未转入") || textContains(content, "开工未转")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null;
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendMassageStartedNotTransIn(
|
||||
conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
bizLogger.info("已触发开工未转入数据发送");
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发开工未转入数据发送失败", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 未及时转移
|
||||
if (content != null && content.contains("未及时转移")) {
|
||||
if (textContains(content, "未及时转移")) {
|
||||
isHandled = true;
|
||||
String sessionWebhook = null; // 不再使用 webhook
|
||||
String senderId = eventJson.getString("senderStaffId");
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
kingdeeWorkCenterDataController.sendProcessTransferForm(conversationId, sessionWebhook, senderId, SAFETY_STOCK_ROBOT_CODE);
|
||||
kingdeeWorkCenterDataController.sendProcessTransferForm(conversationId, sessionWebhook, senderId, dingTalkProperties.getSafetyStockRobotCode());
|
||||
} catch (Exception e) {
|
||||
bizLogger.error("触发未及时转移发送失败", e);
|
||||
}
|
||||
@ -380,7 +605,7 @@ public class CallbackController {
|
||||
String conversationId = eventJson.getString("conversationId");
|
||||
|
||||
if (conversationId != null && !conversationId.isEmpty()) {
|
||||
String helpContent = "您好,我是数据提醒机器人。收到您的消息,但不知道你在讲什么?。\n" + "目前支持以下业务指令,请直接回复关键词:\n" + "1. 安全库存\n" + "2. 延期\n" + "3. 预警\n" + "4. 采购 / 采购申请\n" + "5. 工序汇报 / 未入库\n" + "6. 未及时转移";
|
||||
String helpContent = "您好,我是数据提醒机器人。收到您的消息,但不知道你在讲什么?。\n" + "目前支持以下业务指令,请直接回复关键词:\n" + "1. 安全库存\n" + "2. 延期\n" + "3. 预警\n" + "4. 采购 / 采购申请\n" + "5. 工序汇报未质检 / 质检未入库\n" + "6. 未及时转移\n" + "7. 已转入未转出 / 转入但部分转出 / 部分转出\n" + "8. 开工未转入 / 开工未转";
|
||||
|
||||
// 使用回调中的 sessionWebhook 直接回复 (这是最标准的回调回复方式)
|
||||
if (sessionWebhook != null && !sessionWebhook.isEmpty()) {
|
||||
@ -393,7 +618,6 @@ public class CallbackController {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@ -406,13 +630,13 @@ public class CallbackController {
|
||||
if (eventJson.containsKey("robotCode")) {
|
||||
String robotCode = eventJson.getString("robotCode");
|
||||
// 如果是安全库存机器人
|
||||
if (SAFETY_STOCK_ROBOT_CODE.equals(robotCode) ||
|
||||
if (dingTalkProperties.getSafetyStockRobotCode().equals(robotCode) ||
|
||||
(dingTalkProperties.getSafetyStockAppKey() != null && dingTalkProperties.getSafetyStockAppKey().equals(robotCode))) {
|
||||
String appKey = dingTalkProperties.getSafetyStockAppKey();
|
||||
String appSecret = dingTalkProperties.getSafetyStockAppSecret();
|
||||
// 兜底:如果配置为空,使用常量
|
||||
if (appKey == null || appKey.isEmpty()) {
|
||||
appKey = SAFETY_STOCK_ROBOT_CODE;
|
||||
appKey = dingTalkProperties.getSafetyStockRobotCode();
|
||||
}
|
||||
// 动态获取 Token
|
||||
bizLogger.info("使用安全库存机器人Token: robotCode={}", robotCode);
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
package com.ruoyi.web.controller.system;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.SysLoginService;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@ -23,16 +21,18 @@ public class PlmAuthController {
|
||||
|
||||
private final SysLoginService loginService;
|
||||
|
||||
/**
|
||||
* PLM 获取本系统 Sa-Token。支持 JSON 体或表单/query 参数(避免客户端未带 Content-Type 导致 415)。
|
||||
*/
|
||||
@SaIgnore
|
||||
@PostMapping(value = "/token", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public R<Map<String, Object>> token(@RequestBody PlmTokenRequest body) {
|
||||
if (body == null || StringUtils.isBlank(body.getAppKey()) || StringUtils.isBlank(body.getAppSecret())) {
|
||||
@PostMapping("/token")
|
||||
public R<Map<String, Object>> token(@RequestBody(required = false) PlmTokenRequest body,@RequestParam(required = false) String appKey, @RequestParam(required = false) String appSecret) {
|
||||
String key = body != null && StringUtils.isNotBlank(body.getAppKey()) ? body.getAppKey() : appKey;
|
||||
String secret = body != null && StringUtils.isNotBlank(body.getAppSecret()) ? body.getAppSecret() : appSecret;
|
||||
if (StringUtils.isBlank(key) || StringUtils.isBlank(secret)) {
|
||||
return R.fail("appKey/appSecret不能为空");
|
||||
}
|
||||
String token = loginService.plmToken(body.getAppKey(), body.getAppSecret());
|
||||
Map<String, Object> data = new HashMap<>(2);
|
||||
data.put(Constants.TOKEN, token);
|
||||
return R.ok(data);
|
||||
return R.ok(loginService.plmToken(key, secret));
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
@ -50,8 +50,8 @@ spring:
|
||||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
||||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
||||
# 本机双实例:5.7 常用 3306,8.0 常用其它端口(示例 3307);内网库另见下行注释
|
||||
#url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://localhost:3307/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://localhost:3306/item_\retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo-test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
@ -62,7 +62,8 @@ spring:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
#url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://localhost:3307/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://192.168.5.121:3306/item_retrieval_salve-test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
sqlserver:
|
||||
@ -161,3 +162,8 @@ sms:
|
||||
signName: 测试
|
||||
# 腾讯专用
|
||||
sdkAppId:
|
||||
|
||||
--- # PLM 方案申请推送(开发环境可覆盖 base-url,须含端口与 /api/)
|
||||
plm:
|
||||
sale-plan:
|
||||
base-url: http://192.168.5.20:8081/api/
|
||||
@ -1,6 +1,11 @@
|
||||
--- # 临时文件存储位置 避免临时文件被系统清理报错
|
||||
spring.servlet.multipart.location: /ruoyi/server/temp
|
||||
|
||||
--- # 图纸 DWG 上传暂存(应用服务器本地,非电子档案 E: 盘)
|
||||
app:
|
||||
drawing:
|
||||
upload-staging-dir: /ruoyi/server/temp/dwg-upload
|
||||
|
||||
--- # 监控中心配置
|
||||
spring.boot.admin.client:
|
||||
# 增加客户端开关
|
||||
@ -62,7 +67,7 @@ spring:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
#url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: root
|
||||
password: root
|
||||
sqlserver:
|
||||
|
||||
@ -63,6 +63,8 @@ user:
|
||||
spring:
|
||||
application:
|
||||
name: ${ruoyi.name}
|
||||
config:
|
||||
import: optional:classpath:plm-pdf-mark.yml
|
||||
http:
|
||||
connect-timeout: 10000
|
||||
read-timeout: 20000
|
||||
@ -70,6 +72,7 @@ spring:
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
encoding: UTF-8
|
||||
profiles:
|
||||
active: '@profiles.active@'
|
||||
# 文件上传
|
||||
@ -104,9 +107,9 @@ sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: Authorization
|
||||
# token有效期 设为一天 (必定过期) 单位: 秒
|
||||
timeout: 986400
|
||||
timeout: 86400
|
||||
# token临时有效期 (指定时间无操作就过期) 单位: 秒
|
||||
activity-timeout: 99999
|
||||
activity-timeout: 86400
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
@ -156,6 +159,9 @@ security:
|
||||
- /system/operationPlanningMain/sync
|
||||
- /system/operationPlanningMain/cascadeList
|
||||
- /system/operationPlanningMain/queryFromK3
|
||||
- /system/route/push/**
|
||||
- /DataBoard/ProduceKanBan/**
|
||||
- /system/workCenterData/produceDataKanban
|
||||
|
||||
# MyBatisPlus配置
|
||||
# https://baomidou.com/config/
|
||||
@ -296,17 +302,102 @@ management:
|
||||
logfile:
|
||||
external-file: ./logs/sys-console.log
|
||||
dingtalk:
|
||||
#钉钉应用Key
|
||||
app-key: dingebfrpzqko25vo8w6
|
||||
#钉钉应用Secret
|
||||
app-secret: M_hoza71hmEqsbbeXM-7MBg67EINqi9C6mKj4zWKQysXN-68GCYYc5DZoV0hXVvk
|
||||
#钉钉机器人Code
|
||||
robot-code: dingebfrpzqko25vo8w6
|
||||
#安全库存应用Key
|
||||
safety-stock-app-key: dingwoaeaozawfochwoo
|
||||
#安全库存应用Secret
|
||||
safety-stock-app-secret: rGrAQ7cReWeYzIK5j71l8d2qOLgUTyc-qnlacQcl3n0dKG3M8bgbbaSoc9AbKeUy
|
||||
#安全库存机器人ID
|
||||
safety-stock-agent-id: 35823003
|
||||
#安全库存开放会话ID
|
||||
open-conversation-id: ciddXVuhDM6kJZPJ3o+RcOBqQ==
|
||||
# 信息发送机器人(项目进度 / 延期全工段汇总多Sheet 私发);AppSecret 须填钉钉开放平台该应用密钥
|
||||
info-send-app-key: ding9bhxctsmq5jsf8pk
|
||||
info-send-app-secret: OBhuwZzf31kcVqqVwODtu59Aqmql21gc301V06Y8URdjZy_YmBJ47-AZ4nnLZVVm
|
||||
info-send-robot-code: ding9bhxctsmq5jsf8pk
|
||||
info-send-user-ids: "665416234832653417,283633411029629036,0754423610937470"
|
||||
#项目卡片模板ID
|
||||
project-card-template-id: 2b7bd7ab-0a20-43f2-902c-71198a8dd6a1.schema
|
||||
#工艺审核互动卡片模板ID
|
||||
route-card-template-id: 58244f90-b92d-4ab9-b619-8e83cef67d0c.schema
|
||||
#工艺审核互动卡片回调路由Key
|
||||
callback-route-key: update_route_status2
|
||||
notify-user-id: 0754423610937470
|
||||
route-approval-id: 01201038164023402380
|
||||
plan-user-id: 313514580637707245,192530665123549546
|
||||
sync-k3-notify-user-ids: 313514580637707245,351225426738742993,192530665123549546
|
||||
# 出图完成通知(钉钉 userId/staffId,多人逗号分隔;以 0 开头的须加引号)
|
||||
notify-user-id: "173769650335444471,0108392663561185496,283633411029629036"
|
||||
# 工艺审核互动卡片
|
||||
route-approval-id: "01201038164023402380"
|
||||
# 工艺计划推送用户
|
||||
plan-user-id: "313514580637707245,02256761642526333139,192530665123549546,01201038164023402380"
|
||||
# 同步K3通知用户
|
||||
sync-k3-notify-user-ids: "313514580637707245,02256761642526333139,192530665123549546"
|
||||
#技术方案申请流程编码
|
||||
scheme-application-process-code: PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB
|
||||
#技术方案申请流程同意后是否推送PLM
|
||||
scheme-bpms-on-instance-agree: true
|
||||
#技术方案申请流程任务同意后是否推送PLM
|
||||
scheme-bpms-on-task-agree: false
|
||||
#技术方案申请流程任务同意后推送PLM显示名称
|
||||
scheme-bpms-plm-push-task-show-names: 总工程师
|
||||
#技术方案申请流程同意后推送PLM是否显示总工程师意见
|
||||
scheme-bpms-plm-push-on-chief-opinion-filled: true
|
||||
|
||||
# 图纸档案 FTP:同机 14.218,下载 21 / 上传 8022(8022 登录根目录=电子档案/1.标准图纸存放文件夹)
|
||||
app:
|
||||
drawing:
|
||||
# DWG 上传在应用服务器上的暂存目录(须可写);实际上传目标走 FTP 8022
|
||||
upload-staging-dir: D:/file/dwg-upload
|
||||
# 工艺计划表落盘目录(手动上传 / PLM 导出共用;下按生产令号分子目录)
|
||||
plan-excel:
|
||||
base-dir: D:/file/plan-excel
|
||||
ftp:
|
||||
download:
|
||||
host: 192.168.14.218
|
||||
port: 21
|
||||
username: admin
|
||||
password: hbyt2025
|
||||
upload:
|
||||
host: 192.168.14.218
|
||||
port: 8022
|
||||
username: admin
|
||||
password: hbyt2025
|
||||
|
||||
# PLM 对接(/plm/token 鉴权、PDF 图纸接收、钉钉方案申请推送等)
|
||||
plm:
|
||||
pdf:
|
||||
base-dir: D:/plm/pdf
|
||||
separator: '_'
|
||||
# 左栏标注坐标见独立配置 plm-pdf-mark.yml(按 A4/A3/A3横/A2 等图幅匹配)
|
||||
auth:
|
||||
# 与 PLM 调用 /plm/token 时传入的 appKey、appSecret 一致
|
||||
app-key: plm
|
||||
app-secret: change-me-plm-secret
|
||||
# 本系统 sys_user.user_name,须已存在且可登录,用于签发 Sa-Token
|
||||
username: plm_bot
|
||||
# 钉钉技术方案申请表 → PLM sales/saleplanapplyform(出站)
|
||||
sale-plan:
|
||||
enabled: true
|
||||
# 须含 /api/,与 PLM 一致:POST {base-url}Login → http://host:8081/api/Login
|
||||
base-url: http://192.168.5.20:8081/api/
|
||||
login-path: Login
|
||||
submit-path: sales/saleplanapplyform
|
||||
username: 钉钉
|
||||
password: "123"
|
||||
token-header: Authorization
|
||||
token-prefix: "Bearer "
|
||||
# 副总工程师姓名→工号见代码 DingSchemeDeputyChiefNameMap(zpdfzgcs)
|
||||
# 钉钉附件:grantProcessInstanceForDownloadFile → multipart/form-data files 直传 PLM
|
||||
attachments-enabled: true
|
||||
attachment-field: files
|
||||
max-attachment-files: 20
|
||||
# 单附件上限 100MB
|
||||
max-attachment-bytes-per-file: 104857600
|
||||
read-timeout-ms: 600000
|
||||
ding-attachment-download-timeout-ms: 600000
|
||||
# 库内 DDAttachment 常为空时,推送前再从钉钉 getProcessInstance 拉附件
|
||||
refresh-attachments-from-ding-on-push: true
|
||||
log-payload-max-chars: 8000
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
#??ID-PROD
|
||||
#ID-PROD
|
||||
X-KDApi-AcctID = 69d0e0f3a5801e
|
||||
X-KDApi-UserName = Administrator
|
||||
#??IDID
|
||||
#IDID
|
||||
X-KDApi-AppID = 288012_Rc0C0zCG2lga0/Vs2Y4pzYSL6hQcWOko
|
||||
# ??
|
||||
X-KDApi-AppSec = 8a76cd746fa24636b2c65ef9f313c640
|
||||
X-KDApi-ServerUrl =http://192.168.5.8/K3Cloud/
|
||||
X-KDApi-LCID = 2052
|
||||
|
||||
172
ruoyi-admin/src/main/resources/plm-pdf-mark.yml
Normal file
172
ruoyi-admin/src/main/resources/plm-pdf-mark.yml
Normal file
@ -0,0 +1,172 @@
|
||||
# PLM PDF 左栏标注坐标(伊特图框:本批数量 / 单台数量 / 发图时间 / 生产令号)
|
||||
# 修改后重启生效。坐标为相对页宽/页高的比例,原点在 PDF 左下角。
|
||||
#
|
||||
# 匹配规则:首页 MediaBox 宽高与 width-pt、height-pt 相差不超过 tolerance-pt;
|
||||
# allow-swap: true 时横竖互换也可匹配。
|
||||
# 列表顺序优先:加长/横版专用项在前,避免被竖版 allow-swap 误命中。
|
||||
# 未命中任何项时使用 default-format。
|
||||
# 注意:A4 / A3 / A3_LANDSCAPE / A2 / A2_LANDSCAPE 为已目视调好的坐标,请勿改动 ratio。
|
||||
#
|
||||
# 样本文件 ↔ 配置 id 对应关系(调试样本 / _mark_debug):
|
||||
# 1-A0.pdf → A0_LANDSCAPE
|
||||
# 2-A0-plus.pdf → A0_PLUS_LANDSCAPE
|
||||
# 3-A1.pdf → A1_LANDSCAPE
|
||||
# 4-A1-PLUS.pdf → A1_PLUS_0_5_LANDSCAPE
|
||||
# 5-A2.pdf → A2_LANDSCAPE
|
||||
# 6-A2-PLUS.pdf → A2_PLUS_0_5_LANDSCAPE
|
||||
# 7-A3.pdf → A3_LANDSCAPE
|
||||
# 8-A3-plus.pdf → A3_PLUS_0_5_LANDSCAPE
|
||||
# 9-A3x2.pdf → A3_PLUS_1_LANDSCAPE
|
||||
# 10-A4.pdf → A4
|
||||
|
||||
plm:
|
||||
pdf:
|
||||
mark:
|
||||
rotation: 90
|
||||
font-size: 10
|
||||
default-format: A4
|
||||
formats:
|
||||
|
||||
# --- A0+ 横 5057 × 2384|样本 2-A0-plus.pdf ---
|
||||
- id: A0_PLUS_LANDSCAPE
|
||||
width-pt: 5057.00
|
||||
height-pt: 2384.00
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.0376
|
||||
batch-qty-y-ratio: 0.23
|
||||
unit-qty-y-ratio: 0.18
|
||||
issue-time-y-ratio: 0.115
|
||||
order-no-y-ratio: 0.067
|
||||
|
||||
# --- A0 横 3370 × 2384|样本 1-A0.pdf ---
|
||||
- id: A0_LANDSCAPE
|
||||
width-pt: 3370.00
|
||||
height-pt: 2384.00
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.043
|
||||
batch-qty-y-ratio: 0.23
|
||||
unit-qty-y-ratio: 0.18
|
||||
issue-time-y-ratio: 0.13
|
||||
order-no-y-ratio: 0.06
|
||||
|
||||
# --- A1+0.5 横 3571.65 × 1683.78|样本 4-A1-PLUS.pdf ---
|
||||
- id: A1_PLUS_0_5_LANDSCAPE
|
||||
width-pt: 3571.65
|
||||
height-pt: 1683.78
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.0433
|
||||
batch-qty-y-ratio: 0.33
|
||||
unit-qty-y-ratio: 0.25
|
||||
issue-time-y-ratio: 0.15
|
||||
order-no-y-ratio: 0.08
|
||||
|
||||
# --- A2+0.5 横 2525.67 × 1190.55|样本 6-A2-PLUS.pdf ---
|
||||
- id: A2_PLUS_0_5_LANDSCAPE
|
||||
width-pt: 2525.67
|
||||
height-pt: 1190.55
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.047
|
||||
batch-qty-y-ratio: 0.45
|
||||
unit-qty-y-ratio: 0.34
|
||||
issue-time-y-ratio: 0.22
|
||||
order-no-y-ratio: 0.11
|
||||
|
||||
# --- A3+1 横 2381.10 × 841.89|样本 9-A3x2.pdf ---
|
||||
- id: A3_PLUS_1_LANDSCAPE
|
||||
width-pt: 2381.10
|
||||
height-pt: 841.89
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.052
|
||||
batch-qty-y-ratio: 0.60
|
||||
unit-qty-y-ratio: 0.47
|
||||
issue-time-y-ratio: 0.28
|
||||
order-no-y-ratio: 0.11
|
||||
|
||||
# --- A1 横 2381.10 × 1683.78|样本 3-A1.pdf ---
|
||||
- id: A1_LANDSCAPE
|
||||
width-pt: 2381.10
|
||||
height-pt: 1683.78
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.0491
|
||||
batch-qty-y-ratio: 0.33
|
||||
unit-qty-y-ratio: 0.24
|
||||
issue-time-y-ratio: 0.15
|
||||
order-no-y-ratio: 0.07
|
||||
|
||||
# --- A3+0.5 横 1785.83 × 841.89|样本 8-A3-plus.pdf ---
|
||||
- id: A3_PLUS_0_5_LANDSCAPE
|
||||
width-pt: 1785.83
|
||||
height-pt: 841.89
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.057
|
||||
batch-qty-y-ratio: 0.60
|
||||
unit-qty-y-ratio: 0.44
|
||||
issue-time-y-ratio: 0.28
|
||||
order-no-y-ratio: 0.12
|
||||
|
||||
# --- A2 横 1683.78 × 1190.55|样本 5-A2.pdf(须在 A2 竖版之前)---
|
||||
- id: A2_LANDSCAPE
|
||||
width-pt: 1683.78
|
||||
height-pt: 1190.55
|
||||
tolerance-pt: 6
|
||||
allow-swap: false
|
||||
x-ratio: 0.059
|
||||
batch-qty-y-ratio: 0.437
|
||||
unit-qty-y-ratio: 0.34
|
||||
issue-time-y-ratio: 0.21
|
||||
order-no-y-ratio: 0.11
|
||||
|
||||
# --- A3 横 1190.55 × 841.89|样本 7-A3.pdf(须在 A3 竖版之前)---
|
||||
- id: A3_LANDSCAPE
|
||||
width-pt: 1190.55
|
||||
height-pt: 841.89
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.074
|
||||
batch-qty-y-ratio: 0.60
|
||||
unit-qty-y-ratio: 0.47
|
||||
issue-time-y-ratio: 0.28
|
||||
order-no-y-ratio: 0.10
|
||||
|
||||
# --- A4 竖 595.28 × 841.89|样本 10-A4.pdf ---
|
||||
- id: A4
|
||||
width-pt: 595.28
|
||||
height-pt: 841.89
|
||||
tolerance-pt: 4
|
||||
x-ratio: 0.12
|
||||
batch-qty-y-ratio: 0.60
|
||||
unit-qty-y-ratio: 0.44
|
||||
issue-time-y-ratio: 0.27
|
||||
order-no-y-ratio: 0.11
|
||||
font-size: 10
|
||||
|
||||
# --- A3 竖 841.89 × 1190.55(无对应横版样本时备用)---
|
||||
- id: A3
|
||||
width-pt: 841.89
|
||||
height-pt: 1190.55
|
||||
tolerance-pt: 4
|
||||
allow-swap: false
|
||||
x-ratio: 0.05
|
||||
batch-qty-y-ratio: 0.62
|
||||
unit-qty-y-ratio: 0.45
|
||||
issue-time-y-ratio: 0.27
|
||||
order-no-y-ratio: 0.1
|
||||
|
||||
# --- A2 竖 1190.55 × 1683.78(无对应横版样本时备用)---
|
||||
- id: A2
|
||||
width-pt: 1190.55
|
||||
height-pt: 1683.78
|
||||
tolerance-pt: 6
|
||||
allow-swap: false
|
||||
x-ratio: 0.038
|
||||
batch-qty-y-ratio: 0.45
|
||||
unit-qty-y-ratio: 0.32
|
||||
issue-time-y-ratio: 0.18
|
||||
order-no-y-ratio: 0.06
|
||||
@ -1,21 +1,7 @@
|
||||
package com.ruoyi;
|
||||
|
||||
import com.ruoyi.common.utils.FtpUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
@SpringBootTest(classes=RuoYiApplication.class)
|
||||
@SpringBootTest(classes = RuoYiApplication.class)
|
||||
public class RuoYiTestApplication {
|
||||
|
||||
|
||||
@Test
|
||||
public void asfsrfsf() throws FileNotFoundException {
|
||||
FtpUtil.uploadFile("192.168.5.18", 8022, "admin", "hbyt2025", "", "test11/111111111/222222", "33333.dwg", new FileInputStream(new File("D:\\dwg\\111111111111111.dwg")));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -118,6 +118,18 @@
|
||||
<artifactId>hutool-extra</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- PLM 图纸压缩包:rar / 7z / tar.gz 等 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.26.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>7.5.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
|
||||
@ -44,6 +44,81 @@ public class DingTalkProperties {
|
||||
*/
|
||||
private String safetyStockAgentId;
|
||||
|
||||
/**
|
||||
* 安全库存机器人所在群(可选)。未配置时主动推送仍用 {@link #openConversationId}。
|
||||
*/
|
||||
private String safetyStockOpenConversationId;
|
||||
|
||||
/**
|
||||
* 信息发送机器人 AppKey(名称:信息发送,用于项目进度私发等)
|
||||
*/
|
||||
private String infoSendAppKey;
|
||||
|
||||
/**
|
||||
* 信息发送机器人 AppSecret
|
||||
*/
|
||||
private String infoSendAppSecret;
|
||||
|
||||
/**
|
||||
* 信息发送机器人 Code(通常与 AppKey 相同)
|
||||
*/
|
||||
private String infoSendRobotCode;
|
||||
|
||||
/**
|
||||
* 信息发送机器人私发接收人 StaffId,逗号分隔(项目进度、延期全工段汇总等)
|
||||
*/
|
||||
private String infoSendUserIds;
|
||||
|
||||
/**
|
||||
* 定时/主动群推送默认 robotCode,与 {@link #openConversationId} 对应。
|
||||
*/
|
||||
public String getDefaultAlertPushRobotCode() {
|
||||
if (robotCode != null && !robotCode.isEmpty()) {
|
||||
return robotCode.trim();
|
||||
}
|
||||
return getSafetyStockRobotCode();
|
||||
}
|
||||
|
||||
public boolean isSafetyStockRobot(String code) {
|
||||
if (code == null || code.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String c = code.trim();
|
||||
return c.equals(getSafetyStockRobotCode())
|
||||
|| (safetyStockAppKey != null && c.equals(safetyStockAppKey.trim()));
|
||||
}
|
||||
|
||||
public boolean isInfoSendRobot(String code) {
|
||||
if (code == null || code.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String c = code.trim();
|
||||
return c.equals(getInfoSendRobotCode())
|
||||
|| (infoSendAppKey != null && c.equals(infoSendAppKey.trim()));
|
||||
}
|
||||
|
||||
/** 信息发送机器人 robotCode,默认 ding9bhxctsmq5jsf8pk */
|
||||
public String getInfoSendRobotCode() {
|
||||
if (infoSendRobotCode != null && !infoSendRobotCode.isEmpty()) {
|
||||
return infoSendRobotCode.trim();
|
||||
}
|
||||
if (infoSendAppKey != null && !infoSendAppKey.isEmpty()) {
|
||||
return infoSendAppKey.trim();
|
||||
}
|
||||
return "ding9bhxctsmq5jsf8pk";
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全库存/数据提醒机器人 robotCode(与 {@link #safetyStockAppKey} 同值,供群关键词回调使用)。
|
||||
* 注意:主动推送到 {@link #openConversationId} 时默认应使用 {@link #robotCode},二者所在群可能不同。
|
||||
*/
|
||||
public String getSafetyStockRobotCode() {
|
||||
if (safetyStockAppKey != null && !safetyStockAppKey.isEmpty()) {
|
||||
return safetyStockAppKey.trim();
|
||||
}
|
||||
return "dingwoaeaozawfochwoo";
|
||||
}
|
||||
|
||||
/**
|
||||
* 群会话 ID
|
||||
*/
|
||||
@ -65,7 +140,7 @@ public class DingTalkProperties {
|
||||
|
||||
|
||||
/**
|
||||
* 接收工艺表格个人用户ID
|
||||
* 接收工艺表格个人用户ID(多个用逗号分隔)
|
||||
*/
|
||||
private String notifyUserId;
|
||||
/**
|
||||
@ -86,7 +161,7 @@ public class DingTalkProperties {
|
||||
/**
|
||||
* 技术方案申请表 OA 模板 processCode(如 PROC-xxx);为空则不处理 BPMS 审批事件
|
||||
*/
|
||||
private String schemeApplicationProcessCode = "";
|
||||
private String schemeApplicationProcessCode = "PROC-81A79B4D-F0EA-4353-9A91-68FD7E3BCEBB";
|
||||
|
||||
/**
|
||||
* 是否在 bpms_instance_change 整单结束且 result=agree 时拉取审批详情(推荐)
|
||||
@ -98,6 +173,17 @@ public class DingTalkProperties {
|
||||
*/
|
||||
private boolean schemeBpmsOnTaskAgree = false;
|
||||
|
||||
/**
|
||||
* 任务同意时触发入库与 PLM 的审批节点 showName(逗号分隔,与 operationRecords.showName 匹配,默认总工程师)。
|
||||
* 审批节点名不在表单 component 列表里,须与钉钉审批流节点名称一致。
|
||||
*/
|
||||
private String schemeBpmsPlmPushTaskShowNames = "总工程师";
|
||||
|
||||
/**
|
||||
* 任务同意且表单「技术总工意见」已有内容时也可触发 PLM(不依赖节点 showName 是否叫总工程师)。
|
||||
*/
|
||||
private boolean schemeBpmsPlmPushOnChiefOpinionFilled = true;
|
||||
|
||||
/**
|
||||
* 拉取详情后日志中输出的控件名称(逗号分隔);为空则输出全部非空表单字段
|
||||
*/
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 图纸 FTP:同一台 192.168.14.218,下载 21 端口、上传 8022 端口(登录根目录为电子档案)。
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "app.ftp")
|
||||
public class DrawingFtpProperties {
|
||||
|
||||
/** PDF/DWG 等从出图库下载(端口 21) */
|
||||
private Endpoint download = Endpoint.forDownload();
|
||||
|
||||
/** 图纸上传到电子档案(端口 8022,登录根目录已是 1.标准图纸存放文件夹) */
|
||||
private Endpoint upload = Endpoint.forUpload();
|
||||
|
||||
@Data
|
||||
public static class Endpoint {
|
||||
private String host = "192.168.14.218";
|
||||
private int port = 21;
|
||||
private String username = "admin";
|
||||
private String password = "hbyt2025";
|
||||
|
||||
static Endpoint forDownload() {
|
||||
Endpoint e = new Endpoint();
|
||||
e.setHost("192.168.14.218");
|
||||
e.setPort(21);
|
||||
return e;
|
||||
}
|
||||
|
||||
static Endpoint forUpload() {
|
||||
Endpoint e = new Endpoint();
|
||||
e.setHost("192.168.14.218");
|
||||
e.setPort(8022);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PLM PDF 左栏标注坐标配置(见 classpath:plm-pdf-mark.yml)。
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "plm.pdf.mark")
|
||||
public class PlmPdfMarkProperties {
|
||||
|
||||
/** 逆时针旋转角,伊特左栏竖排一般为 90 */
|
||||
private float rotation = 90f;
|
||||
|
||||
/** 默认字号(各图幅 font-size 为 0 时使用) */
|
||||
private int fontSize = 10;
|
||||
|
||||
/** 未匹配到任何图幅时使用的 format id */
|
||||
private String defaultFormat = "A4";
|
||||
|
||||
/** 按 PDF 首页宽高(pt)匹配;列表顺序优先(先配更具体的尺寸) */
|
||||
private List<FormatProfile> formats = new ArrayList<>();
|
||||
|
||||
@Data
|
||||
public static class FormatProfile {
|
||||
|
||||
/** 图幅标识,日志与 default-format 引用 */
|
||||
private String id;
|
||||
|
||||
/** 参考页宽(pt),与 PDF MediaBox 一致 */
|
||||
private float widthPt;
|
||||
|
||||
/** 参考页高(pt) */
|
||||
private float heightPt;
|
||||
|
||||
/** 宽高允许偏差(pt) */
|
||||
private float tolerancePt = 4f;
|
||||
|
||||
/** 是否允许宽高互换后匹配(横竖版) */
|
||||
private boolean allowSwap = true;
|
||||
|
||||
private float xRatio = 0.048f;
|
||||
private float batchQtyYRatio = 0.69f;
|
||||
private float unitQtyYRatio = 0.52f;
|
||||
private float issueTimeYRatio = 0.35f;
|
||||
private float orderNoYRatio = 0.18f;
|
||||
|
||||
/** 0 表示使用全局 font-size */
|
||||
private int fontSize = 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 钉钉方案申请 → PLM 售前方案申请单(sales/saleplanapplyform)对接配置。
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "plm.sale-plan")
|
||||
public class PlmSalePlanProperties {
|
||||
|
||||
/** 是否启用推送 */
|
||||
private boolean enabled = false;
|
||||
|
||||
|
||||
private String baseUrl = "http://192.168.5.20:8081/api/";
|
||||
|
||||
/** 登录接口相对路径(请求体 UserName、Password) */
|
||||
private String loginPath = "Login";
|
||||
|
||||
/** 提交接口相对路径 */
|
||||
private String submitPath = "sales/saleplanapplyform";
|
||||
|
||||
private String username = "钉钉";
|
||||
|
||||
private String password = "123";
|
||||
|
||||
/** 提交时 Token 请求头名 */
|
||||
private String tokenHeader = "Authorization";
|
||||
|
||||
/** Token 前缀,如 Bearer */
|
||||
private String tokenPrefix = "Bearer ";
|
||||
|
||||
/** 连接超时(毫秒) */
|
||||
private int connectTimeoutMs = 15000;
|
||||
|
||||
/** 读取超时(毫秒);大附件 multipart 上传 PLM 建议 ≥300000 */
|
||||
private int readTimeoutMs = 600_000;
|
||||
|
||||
/** 是否下载钉钉附件并以 multipart files 直传 PLM */
|
||||
private boolean attachmentsEnabled = true;
|
||||
|
||||
/** PLM multipart 附件字段名 */
|
||||
private String attachmentField = "files";
|
||||
|
||||
private int maxAttachmentFiles = 20;
|
||||
|
||||
/** 单附件最大字节数,默认 100MB(支持 STEP 等大文件) */
|
||||
private int maxAttachmentBytesPerFile = 100 * 1024 * 1024;
|
||||
|
||||
/** 钉钉 OSS 单文件下载超时(毫秒) */
|
||||
private int dingAttachmentDownloadTimeoutMs = 600_000;
|
||||
|
||||
/** 库内 wf/form 无 fileId 时,推送前是否再调 getProcessInstance 拉附件 */
|
||||
private boolean refreshAttachmentsFromDingOnPush = true;
|
||||
|
||||
/** 推送日志中摘要最大长度 */
|
||||
private int logPayloadMaxChars = 8000;
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.common.convert;
|
||||
|
||||
/**
|
||||
* Excel 文本空值归一化:将空串及常见占位文本视为 null。
|
||||
*/
|
||||
final class ExcelNullableText {
|
||||
|
||||
private ExcelNullableText() {
|
||||
}
|
||||
|
||||
static String normalize(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String str = value.trim();
|
||||
if (str.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String lower = str.toLowerCase();
|
||||
if ("null".equals(lower)
|
||||
|| "nul".equals(lower)
|
||||
|| "undefined".equals(lower)
|
||||
|| "nan".equals(lower)
|
||||
|| "n/a".equals(lower)
|
||||
|| "-".equals(str)
|
||||
|| "--".equals(str)
|
||||
|| "/".equals(str)) {
|
||||
return null;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.ruoyi.common.convert;
|
||||
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
|
||||
/**
|
||||
* EasyExcel Double 空值安全转换:空单元格/空字符串返回 null,不抛异常。
|
||||
*/
|
||||
public class NullableDoubleConverter implements Converter<Double> {
|
||||
|
||||
@Override
|
||||
public Class<Double> supportJavaTypeKey() {
|
||||
return Double.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
if (cellData == null || cellData.getType() == null || cellData.getType() == CellDataTypeEnum.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
switch (cellData.getType()) {
|
||||
case NUMBER:
|
||||
return cellData.getNumberValue() == null ? null : cellData.getNumberValue().doubleValue();
|
||||
case STRING:
|
||||
String str = ExcelNullableText.normalize(cellData.getStringValue());
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Double.valueOf(str);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
case BOOLEAN:
|
||||
return cellData.getBooleanValue() == null ? null : (cellData.getBooleanValue() ? 1D : 0D);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<?> convertToExcelData(Double value, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
return value == null ? new WriteCellData<>("") : new WriteCellData<>(String.valueOf(value));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.ruoyi.common.convert;
|
||||
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
|
||||
/**
|
||||
* EasyExcel Long 空值安全转换:空单元格/空字符串返回 null,不抛异常。
|
||||
*/
|
||||
public class NullableLongConverter implements Converter<Long> {
|
||||
|
||||
@Override
|
||||
public Class<Long> supportJavaTypeKey() {
|
||||
return Long.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
if (cellData == null || cellData.getType() == null || cellData.getType() == CellDataTypeEnum.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
switch (cellData.getType()) {
|
||||
case NUMBER:
|
||||
return cellData.getNumberValue() == null ? null : cellData.getNumberValue().longValue();
|
||||
case STRING:
|
||||
String str = ExcelNullableText.normalize(cellData.getStringValue());
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (long) Double.parseDouble(str);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
case BOOLEAN:
|
||||
return cellData.getBooleanValue() == null ? null : (cellData.getBooleanValue() ? 1L : 0L);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
return value == null ? new WriteCellData<>("") : new WriteCellData<>(String.valueOf(value));
|
||||
}
|
||||
}
|
||||
@ -105,14 +105,19 @@ public class DingCallbackCrypto {
|
||||
*/
|
||||
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg)
|
||||
throws DingTalkEncryptException {
|
||||
//校验签名
|
||||
return new String(getDecryptPlainUtf8(msgSignature, timeStamp, nonce, encryptMsg), CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验签后返回解密明文的 UTF-8 字节,避免中间 String 与外层 body 解码互相污染。
|
||||
*/
|
||||
public byte[] getDecryptPlainUtf8(String msgSignature, String timeStamp, String nonce, String encryptMsg)
|
||||
throws DingTalkEncryptException {
|
||||
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
|
||||
if (!signature.equals(msgSignature)) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
|
||||
}
|
||||
// 解密
|
||||
String result = decrypt(encryptMsg);
|
||||
return result;
|
||||
return decryptPlainUtf8Bytes(encryptMsg);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -152,43 +157,35 @@ public class DingCallbackCrypto {
|
||||
* @param text 需要解密的密文
|
||||
* @return 解密得到的明文
|
||||
*/
|
||||
private String decrypt(String text) throws DingTalkEncryptException {
|
||||
private byte[] decryptPlainUtf8Bytes(String text) throws DingTalkEncryptException {
|
||||
byte[] originalArr;
|
||||
try {
|
||||
// 设置解密模式为AES的CBC模式
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
|
||||
// 使用BASE64对密文进行解码
|
||||
byte[] encrypted = Base64.decodeBase64(text);
|
||||
// 解密
|
||||
originalArr = cipher.doFinal(encrypted);
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
|
||||
}
|
||||
|
||||
String plainText;
|
||||
byte[] plainTextBytes;
|
||||
String fromCorpid;
|
||||
try {
|
||||
// 去除补位字符
|
||||
byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
|
||||
// 分离16位随机字符串,网络字节序和corpId
|
||||
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
|
||||
int plainTextLegth = Utils.bytes2int(networkOrder);
|
||||
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
|
||||
plainTextBytes = Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth);
|
||||
fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
|
||||
}
|
||||
|
||||
// corpid不相同的情况
|
||||
if (!fromCorpid.equals(corpId)) {
|
||||
System.out.println("DingCallbackCrypto 校验失败: 传入的 corpId=" + corpId + ", 解密得到的 fromCorpid=" + fromCorpid);
|
||||
// 暂时注释掉抛出异常,以便调试,或者您根据控制台输出修正配置
|
||||
// throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
|
||||
}
|
||||
return plainText;
|
||||
return plainTextBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -14,6 +14,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -120,7 +123,21 @@ public class RobotGroupService {
|
||||
* @param text Markdown内容
|
||||
* @return success
|
||||
*/
|
||||
/**
|
||||
* 支持逗号分隔多个 userId(与 plan-user-id、sync-k3-notify-user-ids 配置一致)。
|
||||
*/
|
||||
public String sendMarkdownToUser(String userId, String title, String text) {
|
||||
List<String> userIds = parseUserIds(userId);
|
||||
if (userIds.isEmpty()) {
|
||||
throw new DingException("接收人 userId 为空");
|
||||
}
|
||||
for (String uid : userIds) {
|
||||
sendMarkdownToSingleUser(uid, title, text);
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
private void sendMarkdownToSingleUser(String userId, String title, String text) {
|
||||
try {
|
||||
Config config = new Config();
|
||||
config.protocol = "https";
|
||||
@ -142,9 +159,8 @@ public class RobotGroupService {
|
||||
|
||||
client.batchSendOTOWithOptions(request, headers, new RuntimeOptions());
|
||||
log.info("机器人个人Markdown消息发送成功, userId: {}, title: {}", userId, title);
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
log.error("机器人个人Markdown消息发送失败", e);
|
||||
log.error("机器人个人Markdown消息发送失败, userId={}", userId, e);
|
||||
throw new DingException("机器人个人Markdown消息发送失败", e);
|
||||
}
|
||||
}
|
||||
@ -158,6 +174,17 @@ public class RobotGroupService {
|
||||
* @return success
|
||||
*/
|
||||
public String sendFileToUser(String userId, String mediaId, String fileName) {
|
||||
List<String> userIds = parseUserIds(userId);
|
||||
if (userIds.isEmpty()) {
|
||||
throw new DingException("接收人 userId 为空");
|
||||
}
|
||||
for (String uid : userIds) {
|
||||
sendFileToSingleUser(uid, mediaId, fileName);
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
private void sendFileToSingleUser(String userId, String mediaId, String fileName) {
|
||||
try {
|
||||
Config config = new Config();
|
||||
config.protocol = "https";
|
||||
@ -178,13 +205,26 @@ public class RobotGroupService {
|
||||
|
||||
client.batchSendOTOWithOptions(request, headers, new com.aliyun.teautil.models.RuntimeOptions());
|
||||
log.info("机器人个人文件发送成功, userId: {}, fileName: {}", userId, fileName);
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
log.error("机器人个人文件发送失败", e);
|
||||
log.error("机器人个人文件发送失败, userId={}", userId, e);
|
||||
throw new DingException("机器人个人文件发送失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** 解析逗号分隔的钉钉 userId / staffId 列表。 */
|
||||
static List<String> parseUserIds(String userIdsCsv) {
|
||||
if (!StringUtils.hasText(userIdsCsv)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String part : userIdsCsv.split(",")) {
|
||||
if (StringUtils.hasText(part)) {
|
||||
result.add(part.trim());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送文本消息到群
|
||||
*
|
||||
|
||||
@ -5,6 +5,8 @@ import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardHeaders;
|
||||
import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardRequest;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
|
||||
import com.aliyun.dingtalkrobot_1_0.models.BatchSendOTOHeaders;
|
||||
import com.aliyun.dingtalkrobot_1_0.models.BatchSendOTORequest;
|
||||
import com.aliyun.dingtalkrobot_1_0.models.OrgGroupSendHeaders;
|
||||
import com.aliyun.dingtalkrobot_1_0.models.OrgGroupSendRequest;
|
||||
import com.aliyun.dingtalkrobot_1_0.models.OrgGroupSendResponse;
|
||||
@ -24,6 +26,7 @@ import org.apache.commons.codec.binary.Base64;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -934,6 +937,74 @@ public class DingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 机器人单聊批量发送 Markdown(BatchSendOTO,最多 20 人/次)。
|
||||
*/
|
||||
public static void batchSendOtoMarkdown(String accessToken, String robotCode, List<String> userIds,
|
||||
String title, String text) {
|
||||
if (userIds == null || userIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Map<String, Object> msgParamMap = new HashMap<>();
|
||||
msgParamMap.put("title", title == null ? "" : title);
|
||||
msgParamMap.put("text", text == null ? "" : text);
|
||||
String msgParam = OBJECT_MAPPER.writeValueAsString(msgParamMap);
|
||||
batchSendOto(accessToken, robotCode, userIds, "sampleMarkdown", msgParam);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("构建单聊 Markdown 参数失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 机器人单聊批量发送文件(BatchSendOTO,最多 20 人/次)。
|
||||
*/
|
||||
public static void batchSendOtoFile(String accessToken, String robotCode, List<String> userIds,
|
||||
String mediaId, String fileName, String fileType) {
|
||||
if (userIds == null || userIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Map<String, Object> msgParamMap = new HashMap<>();
|
||||
msgParamMap.put("mediaId", mediaId);
|
||||
msgParamMap.put("fileName", fileName);
|
||||
if (fileType != null && !fileType.isEmpty()) {
|
||||
msgParamMap.put("fileType", fileType);
|
||||
}
|
||||
String msgParam = OBJECT_MAPPER.writeValueAsString(msgParamMap);
|
||||
batchSendOto(accessToken, robotCode, userIds, "sampleFile", msgParam);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("构建单聊文件参数失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void batchSendOto(String accessToken, String robotCode, List<String> userIds,
|
||||
String msgKey, String msgParam) {
|
||||
try {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = "https";
|
||||
config.regionId = "central";
|
||||
com.aliyun.dingtalkrobot_1_0.Client client = new com.aliyun.dingtalkrobot_1_0.Client(config);
|
||||
|
||||
BatchSendOTOHeaders headers = new BatchSendOTOHeaders();
|
||||
headers.xAcsDingtalkAccessToken = accessToken;
|
||||
|
||||
for (int i = 0; i < userIds.size(); i += 20) {
|
||||
List<String> batch = userIds.subList(i, Math.min(i + 20, userIds.size()));
|
||||
BatchSendOTORequest request = new BatchSendOTORequest()
|
||||
.setRobotCode(robotCode)
|
||||
.setUserIds(new ArrayList<>(batch))
|
||||
.setMsgKey(msgKey)
|
||||
.setMsgParam(msgParam);
|
||||
client.batchSendOTOWithOptions(request, headers, new com.aliyun.teautil.models.RuntimeOptions());
|
||||
}
|
||||
} catch (com.aliyun.tea.TeaException err) {
|
||||
throw new RuntimeException(err);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("机器人单聊发送失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Token 初始化账号 Client(OA 审批 / workflow)
|
||||
*/
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.dingding.workflow;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 钉钉审批表单附件(来自 DDAttachment 控件 value 中的 fileId 等)。
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class DingSchemeAttachmentRef {
|
||||
|
||||
private String componentId;
|
||||
private String fileId;
|
||||
private Long spaceId;
|
||||
private String fileName;
|
||||
private String fileType;
|
||||
private Long fileSize;
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
package com.ruoyi.common.dingding.workflow;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.AddApproveDentryAuthHeaders;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.AddApproveDentryAuthRequest;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.AddApproveDentryAuthRequest.AddApproveDentryAuthRequestFileInfos;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GrantProcessInstanceForDownloadFileHeaders;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GrantProcessInstanceForDownloadFileRequest;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GrantProcessInstanceForDownloadFileResponse;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GrantProcessInstanceForDownloadFileResponseBody;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GrantProcessInstanceForDownloadFileResponseBody.GrantProcessInstanceForDownloadFileResponseBodyResult;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.ruoyi.common.config.PlmSalePlanProperties;
|
||||
import com.ruoyi.common.dingding.token.AccessTokenManager;
|
||||
import com.ruoyi.common.dingding.util.DingUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 钉钉审批附件:先 {@code addApproveDentryAuth} 授权,再 {@code grantProcessInstanceForDownloadFile} 取链,
|
||||
* 最后用原始 URL GET(不可 RestTemplate 重编码,否则 OSS SignatureDoesNotMatch)。
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DingWorkflowAttachmentClient {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DingWorkflowAttachmentClient.class);
|
||||
|
||||
private static final int AUTH_BATCH_SIZE = 10;
|
||||
|
||||
private final AccessTokenManager accessTokenManager;
|
||||
private final PlmSalePlanProperties plmSalePlanProperties;
|
||||
|
||||
public List<DownloadedAttachment> downloadAll(String processInstanceId, String userId,
|
||||
List<DingSchemeAttachmentRef> refs) {
|
||||
if (StrUtil.isBlank(processInstanceId) || refs == null || refs.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (StrUtil.isBlank(userId)) {
|
||||
throw new ServiceException("下载钉钉附件缺少 userId(请使用审批发起人 originatorUserId)");
|
||||
}
|
||||
|
||||
List<DownloadedAttachment> out = new ArrayList<>(refs.size());
|
||||
try {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = DingUtil.createWorkflowClient();
|
||||
String token = accessTokenManager.getAccessToken();
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
|
||||
for (int i = 0; i < refs.size(); i += AUTH_BATCH_SIZE) {
|
||||
List<DingSchemeAttachmentRef> batch = refs.subList(i, Math.min(i + AUTH_BATCH_SIZE, refs.size()));
|
||||
addApproveDentryAuth(client, token, userId, batch, runtime);
|
||||
}
|
||||
|
||||
GrantProcessInstanceForDownloadFileHeaders grantHeaders = new GrantProcessInstanceForDownloadFileHeaders();
|
||||
grantHeaders.xAcsDingtalkAccessToken = token;
|
||||
|
||||
for (DingSchemeAttachmentRef ref : refs) {
|
||||
if (StrUtil.isBlank(ref.getFileId())) {
|
||||
continue;
|
||||
}
|
||||
GrantProcessInstanceForDownloadFileRequest request = new GrantProcessInstanceForDownloadFileRequest()
|
||||
.setProcessInstanceId(processInstanceId)
|
||||
.setFileId(ref.getFileId());
|
||||
GrantProcessInstanceForDownloadFileResponse response =
|
||||
client.grantProcessInstanceForDownloadFileWithOptions(request, grantHeaders, runtime);
|
||||
String downloadUri = extractDownloadUri(response, ref.getFileId());
|
||||
byte[] bytes = fetchPresignedUrlBytes(downloadUri, plmSalePlanProperties.getDingAttachmentDownloadTimeoutMs());
|
||||
out.add(new DownloadedAttachment(ref, bytes));
|
||||
log.info("钉钉附件已下载 processInstanceId={} fileId={} fileName={} bytes={}",
|
||||
processInstanceId, ref.getFileId(), ref.getFileName(), bytes.length);
|
||||
}
|
||||
} catch (ServiceException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
throw new ServiceException("钉钉附件下载异常: " + ex.getMessage());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private static void addApproveDentryAuth(com.aliyun.dingtalkworkflow_1_0.Client client, String token, String userId,
|
||||
List<DingSchemeAttachmentRef> batch, RuntimeOptions runtime) throws Exception {
|
||||
List<AddApproveDentryAuthRequestFileInfos> fileInfos = new ArrayList<>();
|
||||
for (DingSchemeAttachmentRef ref : batch) {
|
||||
if (ref.getSpaceId() == null || StrUtil.isBlank(ref.getFileId())) {
|
||||
continue;
|
||||
}
|
||||
AddApproveDentryAuthRequestFileInfos info = new AddApproveDentryAuthRequestFileInfos();
|
||||
info.setFileId(ref.getFileId());
|
||||
info.setSpaceId(ref.getSpaceId());
|
||||
fileInfos.add(info);
|
||||
}
|
||||
if (fileInfos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
AddApproveDentryAuthRequest authRequest = new AddApproveDentryAuthRequest();
|
||||
authRequest.setUserId(userId);
|
||||
authRequest.setFileInfos(fileInfos);
|
||||
AddApproveDentryAuthHeaders authHeaders = new AddApproveDentryAuthHeaders();
|
||||
authHeaders.xAcsDingtalkAccessToken = token;
|
||||
client.addApproveDentryAuthWithOptions(authRequest, authHeaders, runtime);
|
||||
}
|
||||
|
||||
private static String extractDownloadUri(GrantProcessInstanceForDownloadFileResponse response, String fileId) {
|
||||
GrantProcessInstanceForDownloadFileResponseBody body = response != null ? response.getBody() : null;
|
||||
if (body != null && Boolean.FALSE.equals(body.getSuccess())) {
|
||||
throw new ServiceException("钉钉附件授权失败 fileId=" + fileId);
|
||||
}
|
||||
GrantProcessInstanceForDownloadFileResponseBodyResult result = body != null ? body.getResult() : null;
|
||||
if (result == null || StrUtil.isBlank(result.getDownloadUri())) {
|
||||
throw new ServiceException("钉钉未返回附件下载地址 fileId=" + fileId);
|
||||
}
|
||||
return result.getDownloadUri().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* OSS 预签名 URL:必须原样 GET,保留 Expires/OSSAccessKeyId/Signature 等 query,且不加额外请求头。
|
||||
*/
|
||||
private static byte[] fetchPresignedUrlBytes(String downloadUri, int timeoutMs) {
|
||||
int timeout = timeoutMs > 0 ? timeoutMs : 600_000;
|
||||
HttpResponse resp = HttpRequest.get(downloadUri)
|
||||
.timeout(timeout)
|
||||
.setFollowRedirects(true)
|
||||
.disableCache()
|
||||
.execute();
|
||||
if (!resp.isOk()) {
|
||||
String err = StrUtil.sub(resp.body(), 0, 800);
|
||||
log.warn("OSS 附件下载失败 status={} urlHost={} err={}",
|
||||
resp.getStatus(), hostOf(downloadUri), err);
|
||||
throw new ServiceException("附件下载 HTTP " + resp.getStatus() + ": " + err);
|
||||
}
|
||||
byte[] body = resp.bodyBytes();
|
||||
if (body == null || body.length == 0) {
|
||||
throw new ServiceException("附件下载内容为空");
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
private static String hostOf(String url) {
|
||||
try {
|
||||
int start = url.indexOf("://");
|
||||
if (start < 0) {
|
||||
return url;
|
||||
}
|
||||
int hostStart = start + 3;
|
||||
int hostEnd = url.indexOf('/', hostStart);
|
||||
return hostEnd < 0 ? url.substring(hostStart) : url.substring(hostStart, hostEnd);
|
||||
} catch (Exception ex) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DownloadedAttachment {
|
||||
private final DingSchemeAttachmentRef ref;
|
||||
private final byte[] content;
|
||||
|
||||
public DownloadedAttachment(DingSchemeAttachmentRef ref, byte[] content) {
|
||||
this.ref = ref;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public DingSchemeAttachmentRef getRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,27 +37,35 @@ import java.util.stream.Collectors;
|
||||
* 建议在钉钉侧将订阅范围限定到对应 {@link DingTalkProperties#getSchemeApplicationProcessCode()}。
|
||||
* <p>
|
||||
* {@code bpms_instance_change}:{@code type=finish} 后即拉取详情,是否同意以 {@code getProcessInstance().result} 为准(避免事件体里 result 与详情不一致导致误跳过)。
|
||||
* {@code bpms_task_change}:需 {@code scheme-bpms-on-task-agree=true} 且事件 {@code result=agree}(单节点;若为 audit 等不会处理,请改用实例结束事件)。
|
||||
* {@code bpms_task_change}:拉详情后若整单已 {@code COMPLETED} 且 {@code result=agree} 则入库并推 PLM(末节点同意时常仅有 task 事件、无 instance 事件);
|
||||
* 或节点名/showName 匹配 {@link DingTalkProperties#getSchemeBpmsPlmPushTaskShowNames()};
|
||||
* 或「技术总工意见」已填;或 {@code scheme-bpms-on-task-agree=true}。
|
||||
*/
|
||||
@Component
|
||||
public class SchemeApplicationBpmsEventHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SchemeApplicationBpmsEventHandler.class);
|
||||
|
||||
/** 表单「技术总工意见」控件 id(审批节点名不在 formComponentValues 里) */
|
||||
private static final String CHIEF_ENGINEER_OPINION_COMPONENT_ID = "TextareaField_GO981AG879K0";
|
||||
|
||||
/** 同一 processInstanceId 同时只跑一个拉详情+入库,避免 Stream/HTTP 重复回调并发 insert */
|
||||
private static final ConcurrentHashMap<String, Boolean> PROCESSING = new ConcurrentHashMap<>();
|
||||
|
||||
private final DingTalkProperties properties;
|
||||
private final AccessTokenManager accessTokenManager;
|
||||
private final List<SchemeApplicationApprovedSink> schemeApplicationApprovedSinks;
|
||||
private final List<SchemeApplicationPlmPushSink> schemeApplicationPlmPushSinks;
|
||||
|
||||
public SchemeApplicationBpmsEventHandler(
|
||||
DingTalkProperties properties,
|
||||
AccessTokenManager accessTokenManager,
|
||||
@Autowired(required = false) List<SchemeApplicationApprovedSink> schemeApplicationApprovedSinks) {
|
||||
@Autowired(required = false) List<SchemeApplicationApprovedSink> schemeApplicationApprovedSinks,
|
||||
@Autowired(required = false) List<SchemeApplicationPlmPushSink> schemeApplicationPlmPushSinks) {
|
||||
this.properties = properties;
|
||||
this.accessTokenManager = accessTokenManager;
|
||||
this.schemeApplicationApprovedSinks = schemeApplicationApprovedSinks != null ? schemeApplicationApprovedSinks : Collections.emptyList();
|
||||
this.schemeApplicationPlmPushSinks = schemeApplicationPlmPushSinks != null ? schemeApplicationPlmPushSinks : Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,13 +94,15 @@ public class SchemeApplicationBpmsEventHandler {
|
||||
}
|
||||
|
||||
String eventResult = event.getStr("result");
|
||||
// 整单:事件里 result 可能与详情不一致(甚至为空),只要收到「实例结束」即拉详情,最终以 getProcessInstance.result 为准
|
||||
boolean instanceFinish = eventResult.equals("agree");
|
||||
// 单任务:仍以事件 result=agree 为准(节点上常为 agree;若为 audit 等需开 scheme-bpms-on-task-agree 并扩展白名单)
|
||||
// boolean taskAgree = properties.isSchemeBpmsOnTaskAgree() && "bpms_task_change".equals(eventType) && "agree".equalsIgnoreCase(eventResult);
|
||||
if (!instanceFinish ) {
|
||||
log.info("跳过方案申请表 BPMS:eventType={}, type=finish, eventResult={}, onInstance={}, onTask={}(整单请订阅 bpms_instance_change;仅任务且非 agree 时不会处理)",
|
||||
eventType, eventResult, properties.isSchemeBpmsOnInstanceAgree(), properties.isSchemeBpmsOnTaskAgree());
|
||||
boolean isInstanceChange = "bpms_instance_change".equals(eventType);
|
||||
boolean isTaskChange = "bpms_task_change".equals(eventType);
|
||||
// 整单结束事件:收到 type=finish 即拉详情,是否同意以 getProcessInstance.result 为准
|
||||
boolean instanceFinish = isInstanceChange && properties.isSchemeBpmsOnInstanceAgree();
|
||||
// 单任务同意:先放行拉详情,是否在 pullAndDispatch 入库由整单状态/节点名/技术总工意见等二次判断
|
||||
boolean taskFinishAgree = isTaskChange && "agree".equalsIgnoreCase(eventResult);
|
||||
if (!instanceFinish && !taskFinishAgree) {
|
||||
log.info("跳过方案申请表 BPMS:eventType={}, type=finish, eventResult={}(仅处理 instance_finish 或 task_finish+agree)",
|
||||
eventType, eventResult);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -108,16 +118,23 @@ public class SchemeApplicationBpmsEventHandler {
|
||||
}
|
||||
final String finalEventType = eventType;
|
||||
final String finalEventResult = eventResult;
|
||||
final String taskStaffId = event.getStr("staffId");
|
||||
final String activityName = event.getStr("activityName");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
pullAndDispatch(processInstanceId, finalEventType, finalEventResult);
|
||||
pullAndDispatch(processInstanceId, finalEventType, finalEventResult, taskStaffId, activityName);
|
||||
} finally {
|
||||
PROCESSING.remove(processInstanceId);
|
||||
}
|
||||
}, "scheme-bpms-" + processInstanceId).start();
|
||||
}
|
||||
|
||||
private void pullAndDispatch(String processInstanceId, String triggerEventType, String eventResult) {
|
||||
private void pullAndDispatch(
|
||||
String processInstanceId,
|
||||
String triggerEventType,
|
||||
String eventResult,
|
||||
String taskStaffId,
|
||||
String activityName) {
|
||||
try {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = DingUtil.createWorkflowClient();
|
||||
GetProcessInstanceHeaders headers = new GetProcessInstanceHeaders();
|
||||
@ -132,12 +149,21 @@ public class SchemeApplicationBpmsEventHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties.isSchemeBpmsOnInstanceAgree() && "bpms_instance_change".equals(triggerEventType)) {
|
||||
if ("bpms_instance_change".equals(triggerEventType)) {
|
||||
if (!"agree".equalsIgnoreCase(inst.getResult())) {
|
||||
log.info("整单审批未同意,跳过入库 processInstanceId={} eventResult={} instanceResult={} status={}",
|
||||
processInstanceId, eventResult, inst.getResult(), inst.getStatus());
|
||||
return;
|
||||
}
|
||||
} else if ("bpms_task_change".equals(triggerEventType)) {
|
||||
if (!shouldProcessTaskAgree(inst, taskStaffId, activityName)) {
|
||||
log.info("任务同意但未到 PLM 触发条件,跳过 processInstanceId={} activityName={} staffId={} "
|
||||
+ "instanceResult={} status={} onTaskAgree={} showNames={} chiefOpinionFilled={}",
|
||||
processInstanceId, activityName, taskStaffId, inst.getResult(), inst.getStatus(),
|
||||
properties.isSchemeBpmsOnTaskAgree(), properties.getSchemeBpmsPlmPushTaskShowNames(),
|
||||
properties.isSchemeBpmsPlmPushOnChiefOpinionFilled());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> formMap = toFormFieldMap(inst.getFormComponentValues());
|
||||
@ -153,6 +179,7 @@ public class SchemeApplicationBpmsEventHandler {
|
||||
|
||||
SchemeApplicationApprovedPayload payload = buildPayload(inst, processInstanceId, triggerEventType);
|
||||
notifySinks(payload);
|
||||
notifyPlmPush(processInstanceId);
|
||||
} catch (Exception e) {
|
||||
log.error("拉取方案申请表审批实例失败 processInstanceId={}", processInstanceId, e);
|
||||
}
|
||||
@ -191,6 +218,87 @@ public class SchemeApplicationBpmsEventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单任务同意时是否入库并推 PLM:末节点同意且整单已结束、或命中配置节点名、或技术总工意见已填等。
|
||||
*/
|
||||
private boolean shouldProcessTaskAgree(
|
||||
GetProcessInstanceResponseBodyResult inst,
|
||||
String taskStaffId,
|
||||
String activityName) {
|
||||
if (properties.isSchemeBpmsOnTaskAgree()) {
|
||||
return true;
|
||||
}
|
||||
if (isInstanceCompletedAgree(inst)) {
|
||||
return true;
|
||||
}
|
||||
if (properties.isSchemeBpmsPlmPushOnChiefOpinionFilled()
|
||||
&& hasChiefEngineerOpinion(inst.getFormComponentValues())) {
|
||||
return true;
|
||||
}
|
||||
return matchesConfiguredTaskShowNames(activityName);
|
||||
}
|
||||
|
||||
/** 整单已结束且结果为同意(末节点 task_finish 回调时 instance 事件可能未订阅或晚到)。 */
|
||||
private static boolean isInstanceCompletedAgree(GetProcessInstanceResponseBodyResult inst) {
|
||||
if (inst == null || !"agree".equalsIgnoreCase(inst.getResult())) {
|
||||
return false;
|
||||
}
|
||||
String status = StrUtil.nullToEmpty(inst.getStatus()).trim().toUpperCase();
|
||||
return "COMPLETED".equals(status);
|
||||
}
|
||||
|
||||
/** 回调 {@code activityName} 与配置节点名匹配(SDK operationRecords 无 showName 字段)。 */
|
||||
private boolean matchesConfiguredTaskShowNames(String activityName) {
|
||||
Set<String> wanted = parseCommaSeparatedNames(properties.getSchemeBpmsPlmPushTaskShowNames());
|
||||
if (wanted.isEmpty() || StrUtil.isBlank(activityName)) {
|
||||
return false;
|
||||
}
|
||||
return wanted.contains(activityName.trim());
|
||||
}
|
||||
|
||||
private static boolean hasChiefEngineerOpinion(
|
||||
List<GetProcessInstanceResponseBodyResultFormComponentValues> formValues) {
|
||||
if (CollUtil.isEmpty(formValues)) {
|
||||
return false;
|
||||
}
|
||||
for (GetProcessInstanceResponseBodyResultFormComponentValues c : formValues) {
|
||||
if (c == null) {
|
||||
continue;
|
||||
}
|
||||
if (CHIEF_ENGINEER_OPINION_COMPONENT_ID.equals(c.getId()) && StrUtil.isNotBlank(c.getValue())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Set<String> parseCommaSeparatedNames(String cfg) {
|
||||
if (StrUtil.isBlank(cfg)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
for (String part : cfg.split(",")) {
|
||||
if (StrUtil.isNotBlank(part)) {
|
||||
names.add(part.trim());
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/** 入库完成后推送 PLM(须在 {@link #notifySinks} 之后调用)。 */
|
||||
private void notifyPlmPush(String processInstanceId) {
|
||||
if (schemeApplicationPlmPushSinks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (SchemeApplicationPlmPushSink sink : schemeApplicationPlmPushSinks) {
|
||||
try {
|
||||
sink.pushToPlm(processInstanceId);
|
||||
} catch (Exception ex) {
|
||||
log.error("SchemeApplicationPlmPushSink 执行失败: {}", sink.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Date parseDingDateTime(String iso) {
|
||||
if (StrUtil.isBlank(iso)) {
|
||||
return null;
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.ruoyi.common.dingding.workflow;
|
||||
|
||||
/**
|
||||
* 技术方案申请表审批归档成功后推送 PLM(由 {@link SchemeApplicationBpmsEventHandler} 触发)。
|
||||
*/
|
||||
public interface SchemeApplicationPlmPushSink {
|
||||
|
||||
/**
|
||||
* @param processInstanceId 钉钉审批实例 ID(须已写入 ding_scheme_application)
|
||||
*/
|
||||
void pushToPlm(String processInstanceId);
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.ruoyi.common.poi;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.CellCopyPolicy;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
@ -50,6 +51,60 @@ public class ExcelTemplateProc {
|
||||
saveExportFile(workbook, exportFilePathAndName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一模板多 Sheet 导出:按 sheetConfigs 顺序复制模板页并分别填充,Sheet 名取自 sheetName(通常为工段名)。
|
||||
*/
|
||||
public static void doExportExcelByTemplateProcMultiSheet(String templateFileName,
|
||||
String exportFilePathAndName,
|
||||
List<SheetExportConfig> sheetConfigs) throws IOException {
|
||||
if (sheetConfigs == null || sheetConfigs.isEmpty()) {
|
||||
throw new IllegalArgumentException("sheetConfigs 不能为空");
|
||||
}
|
||||
InputStream inputStream = openTemplateInputStream(templateFileName);
|
||||
XSSFWorkbook workbook;
|
||||
try {
|
||||
workbook = new XSSFWorkbook(inputStream);
|
||||
} finally {
|
||||
inputStream.close();
|
||||
}
|
||||
while (workbook.getNumberOfSheets() > 1) {
|
||||
workbook.removeSheetAt(workbook.getNumberOfSheets() - 1);
|
||||
}
|
||||
for (int i = 1; i < sheetConfigs.size(); i++) {
|
||||
workbook.cloneSheet(0);
|
||||
}
|
||||
for (int i = 0; i < sheetConfigs.size(); i++) {
|
||||
SheetExportConfig config = sheetConfigs.get(i);
|
||||
XSSFSheet sheet = workbook.getSheetAt(i);
|
||||
workbook.setSheetName(i, sanitizeSheetName(config.getSheetName()));
|
||||
dealSheetDataByTemplate(sheet, config.getStaticDataMap(), config.getDynamicDataMappingList());
|
||||
}
|
||||
saveExportFile(workbook, exportFilePathAndName);
|
||||
}
|
||||
|
||||
private static InputStream openTemplateInputStream(String templateFileName) throws IOException {
|
||||
if (templateFileName.startsWith("/") || templateFileName.contains(":")) {
|
||||
return Files.newInputStream(new File(templateFileName).toPath());
|
||||
}
|
||||
ClassPathResource resource = new ClassPathResource(templateFileName);
|
||||
return resource.getInputStream();
|
||||
}
|
||||
|
||||
private static String sanitizeSheetName(String name) {
|
||||
if (name == null || name.isEmpty()) {
|
||||
return "Sheet";
|
||||
}
|
||||
String sanitized = name.replaceAll("[\\\\/*?:\\[\\]]", "");
|
||||
return sanitized.length() > 31 ? sanitized.substring(0, 31) : sanitized;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class SheetExportConfig {
|
||||
private String sheetName;
|
||||
private Map<String, Object> staticDataMap;
|
||||
private List<DynamicDataMapping> dynamicDataMappingList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workbook
|
||||
* @param excelFilePath
|
||||
@ -139,18 +194,6 @@ public class ExcelTemplateProc {
|
||||
continue; // 跳过空行
|
||||
}
|
||||
|
||||
// 添加调试信息:检查每一行是否有静态数据占位符
|
||||
if (row.getFirstCellNum() != -1 && row.getLastCellNum() != -1) {
|
||||
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
|
||||
XSSFCell cell = row.getCell(j);
|
||||
if (cell != null) {
|
||||
String cellValue = cell.getStringCellValue();
|
||||
if (cellValue != null && cellValue.contains("{{") && !cellValue.contains(".")) {
|
||||
System.out.println("发现静态数据占位符: 行" + i + ", 列" + j + ", 内容: " + cellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 先处理静态数据,再处理动态数据
|
||||
dealTemplateDataRow(row, null, staticDataMap);
|
||||
@ -233,11 +276,6 @@ public class ExcelTemplateProc {
|
||||
String replacementValue = entry.getValue() == null ? "" : entry.getValue().toString();
|
||||
cellValue = cellValue.replace(cellTemplateStr, replacementValue);
|
||||
flag = true;
|
||||
// 添加静态数据替换的调试信息
|
||||
if (dataPrefix == null || dataPrefix.isEmpty()) {
|
||||
System.out.println("静态数据替换: " + cellTemplateStr + " -> " + replacementValue);
|
||||
System.out.println("替换后内容: " + cellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class FTPDownload {
|
||||
|
||||
private FTPClient ftpClient;
|
||||
|
||||
public FTPDownload() {
|
||||
ftpClient = new FTPClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到FTP服务器
|
||||
*/
|
||||
public void connect(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) {
|
||||
try {
|
||||
ftpClient.connect(ftpHost, ftpPort);
|
||||
ftpClient.login(ftpUserName, ftpPassword);
|
||||
ftpClient.enterLocalPassiveMode(); // 设置被动模式
|
||||
System.out.println("FTP连接成功!");
|
||||
} catch (IOException e) {
|
||||
System.out.println("FTP连接失败!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出远程目录中的文件
|
||||
* @param remoteDir 远程目录路径
|
||||
* @return FTPFile列表
|
||||
* @throws IOException
|
||||
*/
|
||||
public FTPFile[] listFiles(String remoteDir) throws IOException {
|
||||
return ftpClient.listFiles(remoteDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param remoteFile 远程文件路径
|
||||
* @param localFile 本地保存路径
|
||||
* @throws IOException
|
||||
*/
|
||||
public void downloadFile(String remoteFile, String localFile) throws IOException {
|
||||
try (OutputStream os = new FileOutputStream(localFile)) {
|
||||
ftpClient.retrieveFile(remoteFile, os);
|
||||
System.out.println("文件下载成功: " + remoteFile);
|
||||
} catch (IOException e) {
|
||||
System.out.println("文件下载失败: " + remoteFile);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载整个目录中的所有文件
|
||||
* @param remoteDir 远程目录路径
|
||||
* @param localDir 本地保存目录
|
||||
*/
|
||||
public void downloadFilesInDirectory(String remoteDir, String localDir) {
|
||||
try {
|
||||
FTPFile[] files = listFiles(remoteDir);
|
||||
for (FTPFile file : files) {
|
||||
String remoteFilePath = remoteDir + "/" + file.getName();
|
||||
String localFilePath = localDir + "/" + file.getName();
|
||||
|
||||
if (file.isFile()) {
|
||||
downloadFile(remoteFilePath, localFilePath);
|
||||
} else if (file.isDirectory()) {
|
||||
// 递归下载文件夹
|
||||
File localFolder = new File(localFilePath);
|
||||
if (!localFolder.exists()) {
|
||||
localFolder.mkdirs(); // 创建本地文件夹
|
||||
}
|
||||
downloadFilesInDirectory(remoteFilePath, localFilePath); // 递归下载子文件夹
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("列出文件失败: " + remoteDir);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
FTPDownload ftpDownload = new FTPDownload();
|
||||
String ftpHost = "192.168.5.18"; // FTP服务器IP
|
||||
String ftpUserName = "admin"; // FTP用户名
|
||||
String ftpPassword = "hbyt2025"; // FTP密码
|
||||
int ftpPort = 21; // FTP端口,默认21
|
||||
|
||||
String remoteDir = "/FB-25-039-FS-01/FS25040.03.0-PDF"; // 远程目录
|
||||
String localDir = "F:/FB-25-039-FS-01"; // 本地保存目录
|
||||
|
||||
// 连接到FTP服务器
|
||||
ftpDownload.connect(ftpHost, ftpUserName, ftpPassword, ftpPort);
|
||||
|
||||
// 下载文件
|
||||
ftpDownload.downloadFilesInDirectory(remoteDir, localDir);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
/**
|
||||
* 金蝶物料「存货类别」(FCategoryID.FNumber) 取值规则。
|
||||
*/
|
||||
public final class KingdeeMaterialCategoryHelper {
|
||||
|
||||
/** 半成品 */
|
||||
public static final String SEMI_FINISHED = "007";
|
||||
/** 原材料 */
|
||||
public static final String RAW_MATERIAL = "006";
|
||||
/** 产成品(父级物料默认) */
|
||||
public static final String FINISHED_PRODUCT = "CHLB05_SYS";
|
||||
|
||||
private KingdeeMaterialCategoryHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* BOM 子件 / 明细物料:自制(2)、委外(3)、编码含 -MP → 007;外购(1) → 006。
|
||||
*/
|
||||
public static String resolveChildCategoryFNumber(String erpClsId, String materialCode) {
|
||||
if (containsMp(materialCode)) {
|
||||
return SEMI_FINISHED;
|
||||
}
|
||||
if ("2".equals(erpClsId) || "3".equals(erpClsId)) {
|
||||
return SEMI_FINISHED;
|
||||
}
|
||||
return RAW_MATERIAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* BOM 父级物料:含 -MP → 007;否则产成品 CHLB05_SYS。
|
||||
*/
|
||||
public static String resolveParentCategoryFNumber(String fNumber, String partNumber) {
|
||||
if (containsMp(fNumber) || containsMp(partNumber)) {
|
||||
return SEMI_FINISHED;
|
||||
}
|
||||
return FINISHED_PRODUCT;
|
||||
}
|
||||
|
||||
public static boolean containsMp(String materialCode) {
|
||||
return materialCode != null && materialCode.contains("-MP");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,130 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 工艺路线工段 → 金蝶加工车间(FDepartmentId.FNumber),与金蝶一致。
|
||||
* <pre>
|
||||
* WC000001 机一工段 → 006 机加车间
|
||||
* WC000002 机二工段 → 006 机加车间
|
||||
* WC000004 装一工段 → 007 装配车间
|
||||
* WC000005 装二工段 → 007 装配车间
|
||||
* WC000006 电钳工段 → 007 装配车间
|
||||
* WC000007 下料工段 → 006 机加车间
|
||||
* WC000008 委外中心 → 006 机加车间
|
||||
* WC000010 下料工段 → 018 铆焊车间
|
||||
* WC000011 焊接工段 → 018 铆焊车间
|
||||
* </pre>
|
||||
*/
|
||||
public final class KingdeeRouteDepartmentHelper {
|
||||
|
||||
/** 机加车间 */
|
||||
public static final String DEPT_MACHINE = "006";
|
||||
/** 装配车间 */
|
||||
public static final String DEPT_ASSEMBLY = "007";
|
||||
/** 铆焊车间 */
|
||||
public static final String DEPT_RIVET_WELD = "018";
|
||||
|
||||
/** 006 机加车间 */
|
||||
private static final Set<String> MACHINE_WORKSHOP = setOf(
|
||||
"机一工段", "机二工段", "机加委外");
|
||||
/** 007 装配车间 */
|
||||
private static final Set<String> ASSEMBLY_WORKSHOP = setOf(
|
||||
"装一工段", "装二工段", "电钳工段","装配委外");
|
||||
/** 018 铆焊车间 */
|
||||
private static final Set<String> RIVET_WELD_WORKSHOP = setOf(
|
||||
"下料工段", "焊接工段","铆焊委外");
|
||||
|
||||
public static final List<String> ALLOWED_WORK_CENTERS;
|
||||
static {
|
||||
LinkedHashSet<String> all = new LinkedHashSet<>();
|
||||
all.addAll(MACHINE_WORKSHOP);
|
||||
all.addAll(ASSEMBLY_WORKSHOP);
|
||||
all.addAll(RIVET_WELD_WORKSHOP);
|
||||
ALLOWED_WORK_CENTERS = Collections.unmodifiableList(Arrays.asList(all.toArray(new String[0])));
|
||||
}
|
||||
|
||||
private KingdeeRouteDepartmentHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param workCenter 工段名称(会 trim)
|
||||
* @return 金蝶部门编码 FDepartmentId.FNumber
|
||||
*/
|
||||
public static String resolveDepartmentFNumber(String workCenter) {
|
||||
String wc = normalize(workCenter);
|
||||
if (wc == null) {
|
||||
throw new ServiceException("工作中心(工段)不能为空");
|
||||
}
|
||||
if (MACHINE_WORKSHOP.contains(wc)) {
|
||||
return DEPT_MACHINE;
|
||||
}
|
||||
if (ASSEMBLY_WORKSHOP.contains(wc)) {
|
||||
return DEPT_ASSEMBLY;
|
||||
}
|
||||
if (RIVET_WELD_WORKSHOP.contains(wc)) {
|
||||
return DEPT_RIVET_WELD;
|
||||
}
|
||||
throw new ServiceException("不支持的工作中心「" + wc + "」,仅允许:"
|
||||
+ String.join("、", ALLOWED_WORK_CENTERS));
|
||||
}
|
||||
|
||||
public static String normalize(String workCenter) {
|
||||
if (workCenter == null) {
|
||||
return null;
|
||||
}
|
||||
String s = workCenter.trim();
|
||||
return s.isEmpty() ? null : s;
|
||||
}
|
||||
|
||||
/** 金蝶部门编码 → 加工车间名称(用于校验提示) */
|
||||
public static String departmentLabel(String deptFNumber) {
|
||||
if (DEPT_MACHINE.equals(deptFNumber)) {
|
||||
return "机加车间";
|
||||
}
|
||||
if (DEPT_ASSEMBLY.equals(deptFNumber)) {
|
||||
return "装配车间";
|
||||
}
|
||||
if (DEPT_RIVET_WELD.equals(deptFNumber)) {
|
||||
return "铆焊车间";
|
||||
}
|
||||
return deptFNumber != null ? deptFNumber : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 车间兼容分组:机加(006)、装配(007)视为同一组,可同物料混用;
|
||||
* 铆焊(018)单独成组,不得与机加/装配混用。
|
||||
*/
|
||||
public static String workshopCompatibilityGroup(String deptFNumber) {
|
||||
if (DEPT_MACHINE.equals(deptFNumber) || DEPT_ASSEMBLY.equals(deptFNumber)) {
|
||||
return "MACHINE_ASSEMBLY";
|
||||
}
|
||||
return deptFNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一物料下的加工车间是否冲突。
|
||||
* 仅机加+装配 → 不冲突;含铆焊且同时含其他车间 → 冲突。
|
||||
*/
|
||||
public static boolean hasIncompatibleWorkshops(Set<String> deptFNumbers) {
|
||||
if (deptFNumbers == null || deptFNumbers.size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
LinkedHashSet<String> groups = new LinkedHashSet<>();
|
||||
for (String dept : deptFNumbers) {
|
||||
groups.add(workshopCompatibilityGroup(dept));
|
||||
}
|
||||
return groups.size() > 1;
|
||||
}
|
||||
|
||||
private static Set<String> setOf(String... items) {
|
||||
return Arrays.stream(items).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,11 @@ import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 获取i18n资源文件
|
||||
*
|
||||
@ -24,6 +27,11 @@ public class MessageUtils {
|
||||
* @return 获取国际化翻译值
|
||||
*/
|
||||
public static String message(String code, Object... args) {
|
||||
return MESSAGE_SOURCE.getMessage(code, args, LocaleContextHolder.getLocale());
|
||||
Locale locale = LocaleContextHolder.getLocale();
|
||||
try {
|
||||
return MESSAGE_SOURCE.getMessage(code, args, locale);
|
||||
} catch (NoSuchMessageException ex) {
|
||||
return MESSAGE_SOURCE.getMessage(code, args, code, locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* PLM PDF 左栏标注落点(由 {@link PlmPdfMarkPlacementResolver} 解析)。
|
||||
*/
|
||||
@Getter
|
||||
public class PlmPdfMarkPlacement {
|
||||
|
||||
private final String formatId;
|
||||
private final float markX;
|
||||
private final float[] markY;
|
||||
private final int fontSize;
|
||||
|
||||
public PlmPdfMarkPlacement(String formatId, float markX, float[] markY, int fontSize) {
|
||||
this.formatId = formatId;
|
||||
this.markX = markX;
|
||||
this.markY = markY;
|
||||
this.fontSize = fontSize;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.ruoyi.common.config.PlmPdfMarkProperties;
|
||||
import com.ruoyi.common.config.PlmPdfMarkProperties.FormatProfile;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 按 PDF 首页尺寸匹配 plm-pdf-mark.yml 中的图幅配置。
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PlmPdfMarkPlacementResolver {
|
||||
|
||||
private final PlmPdfMarkProperties properties;
|
||||
|
||||
public float rotation() {
|
||||
return properties.getRotation();
|
||||
}
|
||||
|
||||
public PlmPdfMarkPlacement resolve(float width, float height) {
|
||||
FormatProfile profile = findMatchingProfile(width, height);
|
||||
if (profile == null) {
|
||||
profile = findById(properties.getDefaultFormat());
|
||||
if (profile != null) {
|
||||
log.warn("[PLM PDF 标注] 未匹配图幅 {}x{}pt,回退 default-format={}",
|
||||
width, height, profile.getId());
|
||||
}
|
||||
}
|
||||
if (profile == null && !properties.getFormats().isEmpty()) {
|
||||
profile = properties.getFormats().get(0);
|
||||
log.warn("[PLM PDF 标注] 未匹配图幅 {}x{}pt,回退列表首项 id={}",
|
||||
width, height, profile.getId());
|
||||
}
|
||||
if (profile == null) {
|
||||
log.warn("[PLM PDF 标注] 无图幅配置,使用内置 A4 默认比例 page={}x{}", width, height);
|
||||
return buildPlacement("A4_FALLBACK", width, height, fallbackA4Profile());
|
||||
}
|
||||
return buildPlacement(profile.getId(), width, height, profile);
|
||||
}
|
||||
|
||||
private PlmPdfMarkPlacement buildPlacement(String formatId, float width, float height, FormatProfile profile) {
|
||||
int fontSize = profile.getFontSize() > 0 ? profile.getFontSize() : properties.getFontSize();
|
||||
return new PlmPdfMarkPlacement(
|
||||
formatId,
|
||||
width * profile.getXRatio(),
|
||||
new float[]{
|
||||
height * profile.getBatchQtyYRatio(),
|
||||
height * profile.getUnitQtyYRatio(),
|
||||
height * profile.getIssueTimeYRatio(),
|
||||
height * profile.getOrderNoYRatio()
|
||||
},
|
||||
fontSize
|
||||
);
|
||||
}
|
||||
|
||||
private FormatProfile findMatchingProfile(float width, float height) {
|
||||
List<FormatProfile> formats = properties.getFormats();
|
||||
if (formats == null || formats.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (FormatProfile profile : formats) {
|
||||
if (profile == null || profile.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
if (matches(width, height, profile)) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private FormatProfile findById(String id) {
|
||||
if (id == null || id.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String target = id.trim();
|
||||
for (FormatProfile profile : properties.getFormats()) {
|
||||
if (profile != null && target.equalsIgnoreCase(profile.getId())) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean matches(float width, float height, FormatProfile profile) {
|
||||
float tol = profile.getTolerancePt() > 0 ? profile.getTolerancePt() : 4f;
|
||||
if (nearPair(width, height, profile.getWidthPt(), profile.getHeightPt(), tol)) {
|
||||
return true;
|
||||
}
|
||||
return profile.isAllowSwap()
|
||||
&& nearPair(width, height, profile.getHeightPt(), profile.getWidthPt(), tol);
|
||||
}
|
||||
|
||||
private static boolean nearPair(float w, float h, float refW, float refH, float tol) {
|
||||
return Math.abs(w - refW) <= tol && Math.abs(h - refH) <= tol;
|
||||
}
|
||||
|
||||
private static FormatProfile fallbackA4Profile() {
|
||||
FormatProfile p = new FormatProfile();
|
||||
p.setXRatio(0.048f);
|
||||
p.setBatchQtyYRatio(0.69f);
|
||||
p.setUnitQtyYRatio(0.52f);
|
||||
p.setIssueTimeYRatio(0.35f);
|
||||
p.setOrderNoYRatio(0.18f);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,8 @@ import org.apache.pdfbox.multipdf.PDFMergerUtility;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -114,16 +116,62 @@ public class PDFDocHelper {
|
||||
* @return void
|
||||
*/
|
||||
private static void addDeptReview(PdfContentByte content, Map<String, Object> review,float pswX,float pswY) {
|
||||
addDeptReview(content, review, pswX, pswY, 0);
|
||||
}
|
||||
|
||||
private static void addDeptReview(PdfContentByte content, Map<String, Object> review, float pswX, float pswY, float rotation) {
|
||||
if (Integer.parseInt(String.valueOf(review.get("type"))) == 1) {
|
||||
content.setColorFill(BaseColor.BLACK);
|
||||
} else {
|
||||
content.setColorFill(BaseColor.RED);
|
||||
}
|
||||
// 设置水印位置和内容
|
||||
String result = (String) review.get("result");
|
||||
System.out.println("水印内容:" + result);
|
||||
System.out.println("打印位置坐标:" + pswX + "," + pswY);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, result, pswX, pswY, 0);
|
||||
content.showTextAligned(Element.ALIGN_LEFT, result, pswX, pswY, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 PDF 第 1 页指定位置叠加文字(无图章),经临时文件替换原文件。
|
||||
*/
|
||||
public static void stampTextFirstPage(String pdfPath, List<Map<String, ?>> reviews, float[] pswX, float[] pswY, int fontSize)
|
||||
throws IOException, DocumentException {
|
||||
stampTextFirstPage(pdfPath, reviews, pswX, pswY, fontSize, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 PDF 第 1 页指定位置叠加文字(无图章),经临时文件替换原文件。
|
||||
*
|
||||
* @param rotation 逆时针旋转角度(伊特左栏竖排一般为 90)
|
||||
*/
|
||||
public static void stampTextFirstPage(String pdfPath, List<Map<String, ?>> reviews, float[] pswX, float[] pswY,
|
||||
int fontSize, float rotation) throws IOException, DocumentException {
|
||||
if (reviews == null || reviews.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (pswX == null || pswY == null || pswX.length < reviews.size() || pswY.length < reviews.size()) {
|
||||
throw new IllegalArgumentException("reviews 与坐标数组长度不一致");
|
||||
}
|
||||
File src = new File(pdfPath);
|
||||
File temp = new File(src.getParentFile(), "_plm_stamp_" + src.getName());
|
||||
PdfReader reader = new PdfReader(pdfPath);
|
||||
FileOutputStream fout = new FileOutputStream(temp);
|
||||
PdfStamper stp = new PdfStamper(reader, fout);
|
||||
try {
|
||||
PdfContentByte content = stp.getOverContent(1);
|
||||
content.beginText();
|
||||
content.setFontAndSize(getBaseFont(), fontSize > 0 ? fontSize : 10);
|
||||
for (int t = 0; t < reviews.size(); t++) {
|
||||
Map<String, Object> review = (Map<String, Object>) reviews.get(t);
|
||||
addDeptReview(content, review, pswX[t], pswY[t], rotation);
|
||||
}
|
||||
content.endText();
|
||||
} finally {
|
||||
stp.close();
|
||||
fout.close();
|
||||
reader.close();
|
||||
}
|
||||
Files.move(temp.toPath(), src.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,321 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import com.github.junrar.Archive;
|
||||
import com.github.junrar.rarfile.FileHeader;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* 从 zip / rar / 7z / tar.gz 等压缩包中读取 PDF / DWG。
|
||||
*/
|
||||
public final class PlmPdfArchiveExtractor {
|
||||
|
||||
public static final String SUPPORTED_HINT = "zip、rar、7z、tar、tar.gz、tgz、tar.bz2、gz(单 PDF/DWG)";
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PdfEntryWriter {
|
||||
void writeTo(Path target) throws IOException;
|
||||
}
|
||||
|
||||
/** 持有底层压缩包句柄,用完须 close */
|
||||
public static final class PdfArchiveSession implements AutoCloseable {
|
||||
private final Map<String, PdfEntryWriter> entryWriters;
|
||||
private final Closeable resource;
|
||||
|
||||
private PdfArchiveSession(Map<String, PdfEntryWriter> entryWriters, Closeable resource) {
|
||||
this.entryWriters = entryWriters;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
/** PDF + DWG 条目写入器(key 为压缩包内相对路径) */
|
||||
public Map<String, PdfEntryWriter> getPdfWriters() {
|
||||
return entryWriters;
|
||||
}
|
||||
|
||||
public Map<String, PdfEntryWriter> getEntryWriters() {
|
||||
return entryWriters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (resource != null) {
|
||||
resource.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PlmPdfArchiveExtractor() {
|
||||
}
|
||||
|
||||
public static PdfArchiveSession open(Path archiveFile, String originalName) throws IOException {
|
||||
String type = detectArchiveType(originalName);
|
||||
if (type == null) {
|
||||
throw new IOException("不支持的压缩格式,仅支持: " + SUPPORTED_HINT);
|
||||
}
|
||||
switch (type) {
|
||||
case "zip":
|
||||
return openZip(archiveFile);
|
||||
case "rar":
|
||||
return openRar(archiveFile);
|
||||
case "7z":
|
||||
return open7z(archiveFile);
|
||||
case "tar":
|
||||
return openTar(archiveFile, false, false);
|
||||
case "tar.gz":
|
||||
return openTar(archiveFile, true, false);
|
||||
case "tar.bz2":
|
||||
return openTar(archiveFile, false, true);
|
||||
case "gz":
|
||||
return openGzipSingle(archiveFile, originalName);
|
||||
default:
|
||||
throw new IOException("不支持的压缩格式: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public static String detectArchiveType(String originalName) {
|
||||
if (originalName == null) {
|
||||
return null;
|
||||
}
|
||||
String lower = originalName.trim().toLowerCase(Locale.ROOT);
|
||||
if (lower.endsWith(".tar.gz") || lower.endsWith(".tgz")) {
|
||||
return "tar.gz";
|
||||
}
|
||||
if (lower.endsWith(".tar.bz2") || lower.endsWith(".tbz2")) {
|
||||
return "tar.bz2";
|
||||
}
|
||||
if (lower.endsWith(".zip")) {
|
||||
return "zip";
|
||||
}
|
||||
if (lower.endsWith(".rar")) {
|
||||
return "rar";
|
||||
}
|
||||
if (lower.endsWith(".7z")) {
|
||||
return "7z";
|
||||
}
|
||||
if (lower.endsWith(".tar")) {
|
||||
return "tar";
|
||||
}
|
||||
if (lower.endsWith(".gz")) {
|
||||
return "gz";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String tempFileSuffix(String originalName) {
|
||||
String type = detectArchiveType(originalName);
|
||||
if (type == null) {
|
||||
return ".bin";
|
||||
}
|
||||
switch (type) {
|
||||
case "tar.gz":
|
||||
return ".tar.gz";
|
||||
case "tar.bz2":
|
||||
return ".tar.bz2";
|
||||
case "gz":
|
||||
return ".gz";
|
||||
default:
|
||||
return "." + type;
|
||||
}
|
||||
}
|
||||
|
||||
private static PdfArchiveSession openZip(Path file) throws IOException {
|
||||
ZipFile zf = new ZipFile(file.toFile());
|
||||
Map<String, PdfEntryWriter> map = new LinkedHashMap<>();
|
||||
try {
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
if (ze == null || ze.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String name = normalizeEntryName(ze.getName());
|
||||
if (!isPdfOrDwg(name)) {
|
||||
continue;
|
||||
}
|
||||
putOnce(map, name, target -> {
|
||||
try (InputStream in = zf.getInputStream(ze)) {
|
||||
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
zf.close();
|
||||
throw e;
|
||||
}
|
||||
return new PdfArchiveSession(map, zf);
|
||||
}
|
||||
|
||||
private static PdfArchiveSession openRar(Path file) throws IOException {
|
||||
try {
|
||||
Archive archive = new Archive(file.toFile());
|
||||
Map<String, PdfEntryWriter> map = new LinkedHashMap<>();
|
||||
for (FileHeader fh : archive.getFileHeaders()) {
|
||||
if (fh == null || fh.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String name = normalizeEntryName(fh.getFileName());
|
||||
if (!isPdfOrDwg(name)) {
|
||||
continue;
|
||||
}
|
||||
putOnce(map, name, target -> {
|
||||
try (InputStream in = archive.getInputStream(fh)) {
|
||||
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
});
|
||||
}
|
||||
return new PdfArchiveSession(map, archive);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("解压 RAR 失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static PdfArchiveSession open7z(Path file) throws IOException {
|
||||
SevenZFile sz = SevenZFile.builder().setPath(file).get();
|
||||
Map<String, PdfEntryWriter> map = new LinkedHashMap<>();
|
||||
try {
|
||||
SevenZArchiveEntry entry;
|
||||
while ((entry = sz.getNextEntry()) != null) {
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String name = normalizeEntryName(entry.getName());
|
||||
if (!isPdfOrDwg(name)) {
|
||||
continue;
|
||||
}
|
||||
byte[] data = read7zEntry(sz);
|
||||
putOnce(map, name, target -> Files.write(target, data));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
sz.close();
|
||||
throw e;
|
||||
}
|
||||
return new PdfArchiveSession(map, sz);
|
||||
}
|
||||
|
||||
private static byte[] read7zEntry(SevenZFile sz) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int n;
|
||||
while ((n = sz.read(buffer)) > 0) {
|
||||
baos.write(buffer, 0, n);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
private static PdfArchiveSession openTar(Path file, boolean gzip, boolean bzip2) throws IOException {
|
||||
InputStream raw = Files.newInputStream(file);
|
||||
InputStream compressed = raw;
|
||||
if (gzip) {
|
||||
compressed = new GzipCompressorInputStream(raw);
|
||||
} else if (bzip2) {
|
||||
compressed = new BZip2CompressorInputStream(raw);
|
||||
}
|
||||
TarArchiveInputStream tar = new TarArchiveInputStream(compressed);
|
||||
Map<String, PdfEntryWriter> map = new LinkedHashMap<>();
|
||||
try {
|
||||
collectTarEntries(map, tar);
|
||||
} catch (IOException e) {
|
||||
tar.close();
|
||||
throw e;
|
||||
}
|
||||
return new PdfArchiveSession(map, (Closeable) tar::close);
|
||||
}
|
||||
|
||||
private static void collectTarEntries(Map<String, PdfEntryWriter> map, TarArchiveInputStream tar)
|
||||
throws IOException {
|
||||
ArchiveEntry entry;
|
||||
while ((entry = tar.getNextEntry()) != null) {
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
String name = normalizeEntryName(entry.getName());
|
||||
if (!isPdfOrDwg(name)) {
|
||||
continue;
|
||||
}
|
||||
byte[] data = readAll(tar);
|
||||
putOnce(map, name, target -> Files.write(target, data));
|
||||
}
|
||||
}
|
||||
|
||||
private static PdfArchiveSession openGzipSingle(Path file, String originalName) throws IOException {
|
||||
String entryName = normalizeEntryName(fileNameOnly(originalName));
|
||||
String lower = entryName.toLowerCase(Locale.ROOT);
|
||||
if (!isPdfOrDwg(entryName)) {
|
||||
// 单文件 gzip:无法从内容判断时默认按 PDF 命名
|
||||
if (!lower.endsWith(".pdf") && !lower.endsWith(".dwg")) {
|
||||
entryName = entryName + ".pdf";
|
||||
}
|
||||
}
|
||||
Map<String, PdfEntryWriter> map = new LinkedHashMap<>();
|
||||
String finalName = entryName;
|
||||
map.put(finalName, target -> {
|
||||
try (InputStream in = new GzipCompressorInputStream(Files.newInputStream(file))) {
|
||||
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
});
|
||||
return new PdfArchiveSession(map, null);
|
||||
}
|
||||
|
||||
private static byte[] readAll(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[8192];
|
||||
int n;
|
||||
while ((n = in.read(buf)) != -1) {
|
||||
baos.write(buf, 0, n);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
private static void putOnce(Map<String, PdfEntryWriter> map, String name, PdfEntryWriter writer) throws IOException {
|
||||
if (map.containsKey(name)) {
|
||||
throw new IOException("压缩包内存在重复图纸路径: " + name);
|
||||
}
|
||||
map.put(name, writer);
|
||||
}
|
||||
|
||||
private static boolean isPdfOrDwg(String name) {
|
||||
if (name == null) {
|
||||
return false;
|
||||
}
|
||||
String lower = name.toLowerCase(Locale.ROOT);
|
||||
return lower.endsWith(".pdf") || lower.endsWith(".dwg");
|
||||
}
|
||||
|
||||
public static String normalizeEntryName(String entryName) {
|
||||
String s = entryName == null ? "" : entryName.trim().replace('\\', '/');
|
||||
while (s.startsWith("/")) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
while (s.startsWith("./")) {
|
||||
s = s.substring(2);
|
||||
}
|
||||
if (s.contains("..")) {
|
||||
throw new IllegalArgumentException("非法压缩包路径: " + entryName);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String fileNameOnly(String path) {
|
||||
String s = path == null ? "" : path.replace('\\', '/');
|
||||
int i = s.lastIndexOf('/');
|
||||
return i >= 0 ? s.substring(i + 1) : s;
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,7 @@ public class SmbUtil {
|
||||
}
|
||||
|
||||
// 定位到远程目标子目录
|
||||
SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2025/" + targetFolder + "/", cifs);
|
||||
SmbFile remoteDir = new SmbFile("smb://192.168.14.218/2025/" + targetFolder + "/", cifs);
|
||||
|
||||
if (!remoteDir.exists() || !remoteDir.isDirectory()) {
|
||||
System.err.println("远程目录不存在: " + remoteDir.getCanonicalPath());
|
||||
@ -84,7 +84,7 @@ public class SmbUtil {
|
||||
}
|
||||
|
||||
// 定位到远程目标子目录
|
||||
SmbFile remoteDir = new SmbFile("smb://192.168.5.18/2026/" + targetFolder + "/", cifs);
|
||||
SmbFile remoteDir = new SmbFile("smb://192.168.14.218/2026/" + targetFolder + "/", cifs);
|
||||
|
||||
if (!remoteDir.exists() || !remoteDir.isDirectory()) {
|
||||
System.err.println("远程目录不存在或不是一个目录: " + remoteDir.getCanonicalPath());
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
/**
|
||||
* Maven Surefire 默认 profile=dev 时只运行带 {@code @Category(Dev.class)} 的测试。
|
||||
*/
|
||||
public interface Dev {
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FtpDownloadTest {
|
||||
|
||||
@Test
|
||||
public void testDownload() {
|
||||
String host = "192.168.5.18";
|
||||
int port = 21; // 使用21端口测试下载,根据你之前代F码的默认行为,一般下载用21
|
||||
String username = "admin";
|
||||
String password = "hbyt2025";
|
||||
|
||||
// 你的实际测试路径
|
||||
String remoteDir = "/2026/QB-26-072-XCL"; // 你想测试下载的 FTP 目录
|
||||
String localDir = "D:\\file\\test_download"; // 本地存放目录
|
||||
|
||||
System.out.println("开始测试下载 FTP 目录: " + remoteDir);
|
||||
|
||||
// 调用 FtpUtil 下载文件
|
||||
R<String> result = FtpUtil.downloadFtpDirectoryFiles(
|
||||
host, username, password, port, remoteDir, localDir, null
|
||||
);
|
||||
|
||||
System.out.println("下载结果 Code: " + result.getCode());
|
||||
System.out.println("下载结果 Msg: " + result.getMsg());
|
||||
System.out.println("下载结果 Data: " + result.getData());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,444 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import com.itextpdf.text.Rectangle;
|
||||
import com.itextpdf.text.pdf.PdfReader;
|
||||
import com.ruoyi.common.config.PlmPdfMarkProperties;
|
||||
import com.ruoyi.common.config.PlmPdfMarkProperties.FormatProfile;
|
||||
import com.ruoyi.common.utils.file.PDFDocHelper;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PLM PDF 左栏标注坐标调试工具(配合 plm-pdf-mark.yml)。
|
||||
* <p>
|
||||
* <b>适配规则</b>
|
||||
* <ol>
|
||||
* <li>以 PDF 首页 {@code getPageSizeWithRotation(1)} 的宽高(pt)为准,与 yml 中 {@code width-pt}/{@code height-pt} 比较。</li>
|
||||
* <li>偏差在 {@code tolerance-pt} 内视为命中;{@code allow-swap: true} 时允许横竖互换匹配。</li>
|
||||
* <li>横版专用项(如 A3_LANDSCAPE)应设 {@code allow-swap: false},且写在竖版同尺寸项之前或之后均可,但须 tolerance 足够区分。</li>
|
||||
* <li>加长图幅(A3+0.5、A2+0.5 等)尺寸与标准 A 系不同,须单独增加 format 项;{@code id} 建议与文件名一致。</li>
|
||||
* <li>坐标均为相对页宽/高的比例(0~1),原点在左下角;四条文字自上而下:本批数量、单台数量、发图时间、生产令号。</li>
|
||||
* <li>调试流程:先跑 {@link #scanAndMatchReport()} 看匹配结果 → 再跑 {@link #stampPreview()} 目视核对 → 微调 ratio 后重复。</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* <b>样本文件 ↔ plm-pdf-mark.yml 配置 id 对应关系</b>(样本目录下原文件 → {@code _mark_debug/*_marked.pdf})
|
||||
* <pre>
|
||||
* 1-A0.pdf → A0_LANDSCAPE
|
||||
* 2-A0-plus.pdf → A0_PLUS_LANDSCAPE
|
||||
* 3-A1.pdf → A1_LANDSCAPE
|
||||
* 4-A1-PLUS.pdf → A1_PLUS_0_5_LANDSCAPE
|
||||
* 5-A2.pdf → A2_LANDSCAPE
|
||||
* 6-A2-PLUS.pdf → A2_PLUS_0_5_LANDSCAPE
|
||||
* 7-A3.pdf → A3_LANDSCAPE
|
||||
* 8-A3-plus.pdf → A3_PLUS_0_5_LANDSCAPE
|
||||
* 9-A3x2.pdf → A3_PLUS_1_LANDSCAPE
|
||||
* 10-A4.pdf → A4
|
||||
* </pre>
|
||||
* <p>
|
||||
* 默认样本目录见 {@link #SAMPLE_DIR};输出目录:{@code _mark_debug}。
|
||||
*/
|
||||
@Category(Dev.class)
|
||||
public class PlmPdfMarkDebugTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0 && "stamp".equalsIgnoreCase(args[0])) {
|
||||
new PlmPdfMarkDebugTest().stampPreview();
|
||||
} else {
|
||||
new PlmPdfMarkDebugTest().scanAndMatchReport();
|
||||
}
|
||||
}
|
||||
|
||||
/** 钟铃样本 PDF 目录,可按本机路径修改 */
|
||||
private static final String SAMPLE_DIR = "D:\\新建文件夹\\新建文件夹(2)";
|
||||
|
||||
/** 标注预览输出子目录(不覆盖原文件) */
|
||||
private static final String OUTPUT_SUBDIR = "_mark_debug";
|
||||
|
||||
/** 可用 -Dplm.pdf.mark.yml=绝对路径 覆盖 */
|
||||
private static final String MARK_YML_PROP = "plm.pdf.mark.yml";
|
||||
|
||||
private static final String[] MARK_YML_CANDIDATES = {
|
||||
"ruoyi-admin/src/main/resources/plm-pdf-mark.yml",
|
||||
"../ruoyi-admin/src/main/resources/plm-pdf-mark.yml",
|
||||
"evo-k3cloud/ruoyi-admin/src/main/resources/plm-pdf-mark.yml"
|
||||
};
|
||||
|
||||
private static final String[] LABELS = {"本批99", "单台9", "2026/06/26", "CP-TEST-001"};
|
||||
|
||||
/**
|
||||
* 扫描样本目录下所有 PDF:打印页尺寸、旋转、匹配到的 format id、绝对坐标。
|
||||
* 未命中时会给出建议的 yml 片段(width/height 取实测值)。
|
||||
*/
|
||||
@Test
|
||||
public void scanAndMatchReport() throws Exception {
|
||||
PlmPdfMarkProperties props = loadMarkProperties();
|
||||
PlmPdfMarkPlacementResolver resolver = new PlmPdfMarkPlacementResolver(props);
|
||||
|
||||
File dir = new File(SAMPLE_DIR);
|
||||
if (!dir.isDirectory()) {
|
||||
throw new IllegalStateException("样本目录不存在: " + SAMPLE_DIR);
|
||||
}
|
||||
|
||||
File[] pdfs = dir.listFiles(f -> f.isFile() && f.getName().toLowerCase(Locale.ROOT).endsWith(".pdf"));
|
||||
if (pdfs == null || pdfs.length == 0) {
|
||||
throw new IllegalStateException("目录下无 PDF: " + SAMPLE_DIR);
|
||||
}
|
||||
Arrays.sort(pdfs, (a, b) -> a.getName().compareToIgnoreCase(b.getName()));
|
||||
|
||||
System.out.println("=== PLM PDF 图幅扫描 ===");
|
||||
File ymlFile = resolveMarkYmlFile();
|
||||
System.out.println("配置: " + ymlFile.getAbsolutePath());
|
||||
System.out.println("样本: " + SAMPLE_DIR);
|
||||
System.out.println("rotation=" + props.getRotation() + ", default-format=" + props.getDefaultFormat());
|
||||
System.out.println();
|
||||
|
||||
for (File pdf : pdfs) {
|
||||
PageInfo page = readFirstPage(pdf);
|
||||
PlmPdfMarkPlacement placement = resolver.resolve(page.width, page.height);
|
||||
FormatProfile matchedProfile = findExactProfile(props, page.width, page.height);
|
||||
boolean direct = matchedProfile != null && directMatch(page.width, page.height, matchedProfile);
|
||||
String matchMode = matchedProfile == null ? "FALLBACK"
|
||||
: (direct ? "DIRECT" : "SWAP");
|
||||
|
||||
System.out.println("--- " + pdf.getName() + " ---");
|
||||
System.out.printf(Locale.ROOT, " page=%.2f x %.2f pt, rotation=%d%n",
|
||||
page.width, page.height, page.rotation);
|
||||
System.out.printf(Locale.ROOT, " matched=%s (%s)%n",
|
||||
placement.getFormatId(), matchMode);
|
||||
if ("SWAP".equals(matchMode)) {
|
||||
System.out.println(" >>> 注意: 通过 allow-swap 横竖互换命中,请将专用横版项排在竖版项之前并设 allow-swap: false");
|
||||
}
|
||||
System.out.printf(Locale.ROOT, " markX=%.2f, markY=[%.2f, %.2f, %.2f, %.2f], fontSize=%d%n",
|
||||
placement.getMarkX(),
|
||||
placement.getMarkY()[0], placement.getMarkY()[1],
|
||||
placement.getMarkY()[2], placement.getMarkY()[3],
|
||||
placement.getFontSize());
|
||||
if (matchedProfile == null) {
|
||||
System.out.println(" >>> 建议新增 yml 项(复制后微调 ratio):");
|
||||
System.out.print(suggestYamlSnippet(pdf.getName(), page.width, page.height, props));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按当前 yml 配置对样本 PDF 打测试字,输出到 {@code _mark_debug} 目录供目视核对。
|
||||
*/
|
||||
@Test
|
||||
public void stampPreview() throws Exception {
|
||||
PlmPdfMarkProperties props = loadMarkProperties();
|
||||
PlmPdfMarkPlacementResolver resolver = new PlmPdfMarkPlacementResolver(props);
|
||||
|
||||
File inDir = new File(SAMPLE_DIR);
|
||||
File outDir = new File(inDir, OUTPUT_SUBDIR);
|
||||
if (outDir.exists()) {
|
||||
File[] old = outDir.listFiles();
|
||||
if (old != null) {
|
||||
for (File f : old) {
|
||||
if (!f.delete()) {
|
||||
System.out.println(" 警告: 无法删除旧文件 " + f.getName() + "(若被 PDF 阅读器占用请关闭后重试)");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!outDir.mkdirs()) {
|
||||
throw new IllegalStateException("无法创建输出目录: " + outDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
File[] pdfs = inDir.listFiles(f -> f.isFile() && f.getName().toLowerCase(Locale.ROOT).endsWith(".pdf"));
|
||||
if (pdfs == null || pdfs.length == 0) {
|
||||
throw new IllegalStateException("目录下无 PDF: " + SAMPLE_DIR);
|
||||
}
|
||||
|
||||
System.out.println("=== PLM PDF 标注预览 ===");
|
||||
System.out.println("输出: " + outDir.getAbsolutePath());
|
||||
|
||||
for (File pdf : pdfs) {
|
||||
PageInfo page = readFirstPage(pdf);
|
||||
PlmPdfMarkPlacement placement = resolver.resolve(page.width, page.height);
|
||||
float markX = placement.getMarkX();
|
||||
float[] markY = placement.getMarkY();
|
||||
float[] markXArr = {markX, markX, markX, markX};
|
||||
|
||||
File outFile = new File(outDir, stripPdfExt(pdf.getName()) + "_marked.pdf");
|
||||
Files.copy(pdf.toPath(), outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
List<Map<String, ?>> reviews = buildTestReviews();
|
||||
PDFDocHelper.stampTextFirstPage(outFile.getAbsolutePath(), reviews, markXArr, markY,
|
||||
placement.getFontSize(), props.getRotation());
|
||||
|
||||
System.out.printf(Locale.ROOT, " %s -> %s [%s, %.0fx%.0f]%n",
|
||||
pdf.getName(), outFile.getName(), placement.getFormatId(), page.width, page.height);
|
||||
}
|
||||
System.out.println("完成,请打开 _mark_debug 目录目视核对四条文字是否对齐图框左栏。");
|
||||
}
|
||||
|
||||
// --- helpers ---
|
||||
|
||||
private static PageInfo readFirstPage(File pdf) throws Exception {
|
||||
PdfReader reader = new PdfReader(pdf.getAbsolutePath());
|
||||
try {
|
||||
Rectangle pageSize = reader.getPageSizeWithRotation(1);
|
||||
return new PageInfo(pageSize.getWidth(), pageSize.getHeight(), reader.getPageRotation(1));
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static FormatProfile findExactProfile(PlmPdfMarkProperties props, float w, float h) {
|
||||
if (props.getFormats() == null) {
|
||||
return null;
|
||||
}
|
||||
for (FormatProfile p : props.getFormats()) {
|
||||
if (p == null || p.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
float tol = p.getTolerancePt() > 0 ? p.getTolerancePt() : 4f;
|
||||
if (near(w, h, p.getWidthPt(), p.getHeightPt(), tol)) {
|
||||
return p;
|
||||
}
|
||||
if (p.isAllowSwap() && near(w, h, p.getHeightPt(), p.getWidthPt(), tol)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean near(float w, float h, float rw, float rh, float tol) {
|
||||
return Math.abs(w - rw) <= tol && Math.abs(h - rh) <= tol;
|
||||
}
|
||||
|
||||
private static String suggestYamlSnippet(String fileName, float w, float h, PlmPdfMarkProperties props) {
|
||||
FormatProfile seed = findNearestSeed(w, h, props);
|
||||
String id = suggestId(fileName, w, h);
|
||||
return String.format(Locale.ROOT,
|
||||
" - id: %s%n" +
|
||||
" width-pt: %.2f%n" +
|
||||
" height-pt: %.2f%n" +
|
||||
" tolerance-pt: 4%n" +
|
||||
" allow-swap: false%n" +
|
||||
" x-ratio: %.3f%n" +
|
||||
" batch-qty-y-ratio: %.2f%n" +
|
||||
" unit-qty-y-ratio: %.2f%n" +
|
||||
" issue-time-y-ratio: %.2f%n" +
|
||||
" order-no-y-ratio: %.2f%n",
|
||||
id, w, h,
|
||||
seed.getXRatio(), seed.getBatchQtyYRatio(), seed.getUnitQtyYRatio(),
|
||||
seed.getIssueTimeYRatio(), seed.getOrderNoYRatio());
|
||||
}
|
||||
|
||||
private static FormatProfile findNearestSeed(float w, float h, PlmPdfMarkProperties props) {
|
||||
FormatProfile best = null;
|
||||
double bestDist = Double.MAX_VALUE;
|
||||
for (FormatProfile p : props.getFormats()) {
|
||||
if (p == null) {
|
||||
continue;
|
||||
}
|
||||
double d1 = dist(w, h, p.getWidthPt(), p.getHeightPt());
|
||||
double d2 = dist(w, h, p.getHeightPt(), p.getWidthPt());
|
||||
double d = Math.min(d1, d2);
|
||||
if (d < bestDist) {
|
||||
bestDist = d;
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
return best != null ? best : props.getFormats().get(0);
|
||||
}
|
||||
|
||||
private static double dist(float w, float h, float rw, float rh) {
|
||||
return Math.hypot(w - rw, h - rh);
|
||||
}
|
||||
|
||||
private static boolean directMatch(float w, float h, FormatProfile p) {
|
||||
float tol = p.getTolerancePt() > 0 ? p.getTolerancePt() : 4f;
|
||||
return near(w, h, p.getWidthPt(), p.getHeightPt(), tol);
|
||||
}
|
||||
|
||||
private static String suggestId(String fileName, float w, float h) {
|
||||
String upper = stripPdfExt(fileName).toUpperCase(Locale.ROOT);
|
||||
if (upper.contains("A1+0.5") || upper.contains("A1+0.5")) {
|
||||
return "A1_PLUS_0_5_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A1")) {
|
||||
return "A1_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A2+0.5") || upper.contains("A2+0.5")) {
|
||||
return "A2_PLUS_0_5_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A2")) {
|
||||
return "A2_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A3+1") || upper.contains("A3+1")) {
|
||||
return "A3_PLUS_1_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A3+0.5") || upper.contains("A3+0.5")) {
|
||||
return "A3_PLUS_0_5_LANDSCAPE";
|
||||
}
|
||||
if (upper.contains("A3")) {
|
||||
return w > h ? "A3_LANDSCAPE" : "A3";
|
||||
}
|
||||
if (upper.contains("A4")) {
|
||||
return "A4";
|
||||
}
|
||||
return (w > h ? "CUSTOM_LANDSCAPE" : "CUSTOM") + "_" + Math.round(w) + "x" + Math.round(h);
|
||||
}
|
||||
|
||||
private static String stripPdfExt(String name) {
|
||||
int dot = name.lastIndexOf('.');
|
||||
return dot > 0 ? name.substring(0, dot) : name;
|
||||
}
|
||||
|
||||
private static List<Map<String, ?>> buildTestReviews() {
|
||||
List<Map<String, ?>> reviews = new ArrayList<>(4);
|
||||
for (String label : LABELS) {
|
||||
Map<String, Object> m = new HashMap<>(2);
|
||||
m.put("type", 1);
|
||||
m.put("result", label);
|
||||
reviews.add(m);
|
||||
}
|
||||
return reviews;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static PlmPdfMarkProperties loadMarkProperties() throws Exception {
|
||||
File ymlFile = resolveMarkYmlFile();
|
||||
try (InputStream in = new FileInputStream(ymlFile)) {
|
||||
Map<String, Object> root = new Yaml().load(in);
|
||||
Map<String, Object> mark = (Map<String, Object>) ((Map<String, Object>) ((Map<String, Object>)
|
||||
root.get("plm")).get("pdf")).get("mark");
|
||||
return parseMarkProperties(mark);
|
||||
}
|
||||
}
|
||||
|
||||
/** 兼容 IDEA 工作目录为项目根或 ruoyi-common 模块目录 */
|
||||
private static File resolveMarkYmlFile() {
|
||||
String override = System.getProperty(MARK_YML_PROP);
|
||||
if (override != null && !override.trim().isEmpty()) {
|
||||
File f = new File(override.trim());
|
||||
if (f.isFile()) {
|
||||
return f;
|
||||
}
|
||||
throw new IllegalStateException("系统属性 " + MARK_YML_PROP + " 指向的文件不存在: " + f.getAbsolutePath());
|
||||
}
|
||||
|
||||
File userDir = new File(System.getProperty("user.dir", "."));
|
||||
List<File> tried = new ArrayList<>();
|
||||
|
||||
for (String rel : MARK_YML_CANDIDATES) {
|
||||
File f = new File(userDir, rel);
|
||||
tried.add(f);
|
||||
if (f.isFile()) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
File walk = userDir;
|
||||
for (int i = 0; i < 6 && walk != null; i++) {
|
||||
File f = new File(walk, "ruoyi-admin/src/main/resources/plm-pdf-mark.yml");
|
||||
tried.add(f);
|
||||
if (f.isFile()) {
|
||||
return f;
|
||||
}
|
||||
walk = walk.getParentFile();
|
||||
}
|
||||
|
||||
StringBuilder msg = new StringBuilder("找不到 plm-pdf-mark.yml,已尝试:");
|
||||
for (File f : tried) {
|
||||
msg.append("\n ").append(f.getAbsolutePath());
|
||||
}
|
||||
msg.append("\n可通过 -D").append(MARK_YML_PROP).append("=绝对路径 指定");
|
||||
throw new IllegalStateException(msg.toString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static PlmPdfMarkProperties parseMarkProperties(Map<String, Object> mark) {
|
||||
PlmPdfMarkProperties props = new PlmPdfMarkProperties();
|
||||
props.setRotation(floatVal(mark.get("rotation"), 90f));
|
||||
props.setFontSize(intVal(mark.get("font-size"), 10));
|
||||
props.setDefaultFormat(strVal(mark.get("default-format"), "A4"));
|
||||
|
||||
List<Map<String, Object>> formats = (List<Map<String, Object>>) mark.get("formats");
|
||||
if (formats != null) {
|
||||
List<FormatProfile> list = new ArrayList<>(formats.size());
|
||||
for (Map<String, Object> item : formats) {
|
||||
list.add(parseFormatProfile(item));
|
||||
}
|
||||
props.setFormats(list);
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
private static FormatProfile parseFormatProfile(Map<String, Object> item) {
|
||||
FormatProfile p = new FormatProfile();
|
||||
p.setId(strVal(item.get("id"), null));
|
||||
p.setWidthPt(floatVal(item.get("width-pt"), 0f));
|
||||
p.setHeightPt(floatVal(item.get("height-pt"), 0f));
|
||||
p.setTolerancePt(floatVal(item.get("tolerance-pt"), 4f));
|
||||
p.setAllowSwap(boolVal(item.get("allow-swap"), true));
|
||||
p.setXRatio(floatVal(item.get("x-ratio"), 0.048f));
|
||||
p.setBatchQtyYRatio(floatVal(item.get("batch-qty-y-ratio"), 0.69f));
|
||||
p.setUnitQtyYRatio(floatVal(item.get("unit-qty-y-ratio"), 0.52f));
|
||||
p.setIssueTimeYRatio(floatVal(item.get("issue-time-y-ratio"), 0.35f));
|
||||
p.setOrderNoYRatio(floatVal(item.get("order-no-y-ratio"), 0.18f));
|
||||
p.setFontSize(intVal(item.get("font-size"), 0));
|
||||
return p;
|
||||
}
|
||||
|
||||
private static String strVal(Object v, String def) {
|
||||
return v == null ? def : String.valueOf(v).trim();
|
||||
}
|
||||
|
||||
private static float floatVal(Object v, float def) {
|
||||
if (v == null) {
|
||||
return def;
|
||||
}
|
||||
if (v instanceof Number) {
|
||||
return ((Number) v).floatValue();
|
||||
}
|
||||
return Float.parseFloat(String.valueOf(v));
|
||||
}
|
||||
|
||||
private static int intVal(Object v, int def) {
|
||||
if (v == null) {
|
||||
return def;
|
||||
}
|
||||
if (v instanceof Number) {
|
||||
return ((Number) v).intValue();
|
||||
}
|
||||
return Integer.parseInt(String.valueOf(v));
|
||||
}
|
||||
|
||||
private static boolean boolVal(Object v, boolean def) {
|
||||
if (v == null) {
|
||||
return def;
|
||||
}
|
||||
if (v instanceof Boolean) {
|
||||
return (Boolean) v;
|
||||
}
|
||||
return Boolean.parseBoolean(String.valueOf(v));
|
||||
}
|
||||
|
||||
private static final class PageInfo {
|
||||
final float width;
|
||||
final float height;
|
||||
final int rotation;
|
||||
|
||||
PageInfo(float width, float height, int rotation) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,8 +15,8 @@ spring:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
#url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://localhost:3307/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
#url: jdbc:mysql://localhost:3307/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
hikari:
|
||||
|
||||
@ -14,7 +14,7 @@ spring:
|
||||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/item_retrieval-evo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
|
||||
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: root
|
||||
hikari:
|
||||
|
||||
@ -12,6 +12,7 @@ import com.ruoyi.common.utils.StreamUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.MyBatisSystemException;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
@ -73,6 +74,21 @@ public class GlobalExceptionHandler {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据完整性约束异常(非空、外键等)
|
||||
*/
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public R<Void> handleDataIntegrityViolationException(DataIntegrityViolationException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',数据完整性约束异常", requestURI, e);
|
||||
Throwable cause = e.getMostSpecificCause();
|
||||
String detail = cause != null ? cause.getMessage() : e.getMessage();
|
||||
if (detail != null && (detail.contains("1048") || detail.contains("cannot be null") || detail.contains("不能为null"))) {
|
||||
return R.fail("数据保存失败:存在必填字段为空,请检查Excel中名称、数量等列是否填写完整");
|
||||
}
|
||||
return R.fail("数据保存失败,请检查导入数据是否完整且符合格式要求");
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键或UNIQUE索引,数据重复异常
|
||||
*/
|
||||
|
||||
@ -27,10 +27,6 @@
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-s3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 钉钉「指定/项目负责副总工程师」姓名 → PLM {@code zpdfzgcs} 工号(写死在代码,勿放 yml)。
|
||||
*/
|
||||
public final class DingSchemeDeputyChiefNameMap {
|
||||
|
||||
private DingSchemeDeputyChiefNameMap() {
|
||||
}
|
||||
|
||||
/** 姓名未命中时的默认工号 */
|
||||
public static final String DEFAULT_EMP_NO = "00496";
|
||||
|
||||
/** 「是否为机械标品」=是 时固定推送工号(毕敏霞) */
|
||||
public static final String MECHANICAL_STANDARD_EMP_NO = "00026";
|
||||
|
||||
private static final Map<String, String> NAME_TO_EMP_NO;
|
||||
|
||||
static {
|
||||
Map<String, String> m = new LinkedHashMap<>();
|
||||
m.put("李德山", "00496");
|
||||
m.put("杜惠斌", "00059");
|
||||
// 马杰(钉钉指定副总)→ PLM 接收人毕敏霞 00026
|
||||
m.put("马杰", "00026");
|
||||
NAME_TO_EMP_NO = Collections.unmodifiableMap(m);
|
||||
}
|
||||
|
||||
public static Map<String, String> all() {
|
||||
return NAME_TO_EMP_NO;
|
||||
}
|
||||
|
||||
public static String empNoOf(String displayName) {
|
||||
if (displayName == null || displayName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (String part : splitNames(displayName)) {
|
||||
String empNo = NAME_TO_EMP_NO.get(part);
|
||||
if (empNo != null) {
|
||||
return empNo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String[] splitNames(String displayName) {
|
||||
String normalized = displayName.replace(',', ',').trim();
|
||||
if (!normalized.contains(",")) {
|
||||
return new String[]{normalized};
|
||||
}
|
||||
String[] parts = normalized.split(",");
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
parts[i] = parts[i].trim();
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 钉钉技术方案申请表 {@code form_label_map} 标准对照(控件 id → 中文标题)。
|
||||
* 与 {@link DingSchemeFormWideColumns#ORDERED_IDS} 键集合一致。
|
||||
*/
|
||||
public final class DingSchemeFormLabelMap {
|
||||
|
||||
private DingSchemeFormLabelMap() {
|
||||
}
|
||||
|
||||
private static final Map<String, String> LABELS = build();
|
||||
|
||||
public static Map<String, String> labels() {
|
||||
return LABELS;
|
||||
}
|
||||
|
||||
public static String labelOf(String componentId) {
|
||||
return LABELS.get(componentId);
|
||||
}
|
||||
|
||||
private static Map<String, String> build() {
|
||||
Map<String, String> m = new LinkedHashMap<>();
|
||||
m.put("TextField_1BBYI1OFDJA80", "方案申请编号");
|
||||
m.put("TextField_FRLYG3CQ3CG0", "概述名称");
|
||||
m.put("InnerContactField_9DSIOI7Y7AO0", "填表人");
|
||||
m.put("DDDateField_1BHYQ7T5N5TS0", "填表日期");
|
||||
m.put("DDDateField_YYD1HAMKFXS0", "需求日期");
|
||||
m.put("DDSelectField_1VS1BX17O9MO0", "有无前期对接工程师");
|
||||
m.put("InnerContactField_U886PC45AO00", "前期对接工程师");
|
||||
m.put("TextField_1HXMC0VO5TCW0", "客户全称");
|
||||
m.put("TextField_QBMQQBNCTA80", "联系人及电话");
|
||||
m.put("DDSelectField_845RKMRCBNC", "项目分类");
|
||||
m.put("DDSelectField_1XTHOHPHULNK0", "产品名称");
|
||||
m.put("TextField_1EIAVY538AM80", "产品应用领域");
|
||||
m.put("ColumnLayout_N0ZDGQT4UJ40", "分栏");
|
||||
m.put("DDSelectField_JDD37MSAU7K0", "刚性链类型");
|
||||
m.put("TextField_7KHHS2KML4G0", "台面尺寸");
|
||||
m.put("TextField_1CTQW75A6XK00", "台面尺寸/外形轮廓");
|
||||
m.put("TextField_6JT3ARDIUY40", "外形尺寸(长宽高)");
|
||||
m.put("TextField_1JWDW5KVN95S0", "基坑深度");
|
||||
m.put("TextField_17ONU2GWWQQK0", "行程");
|
||||
m.put("TextField_2E68TAT1P2B", "速度(单位:m/s或mm/s)");
|
||||
m.put("TextField_1D66PIGUHPEO0", "负载(单位:kg)");
|
||||
m.put("DDSelectField_12J1O9KUMFK00", "驱动方式");
|
||||
m.put("DDSelectField_1QQEC44I00G00", "限位方式");
|
||||
m.put("TextField_1FVHYJIFC9340", "最低高度");
|
||||
m.put("DDSelectField_1CTHXMP1W6000", "有无偏载");
|
||||
m.put("DDSelectField_1J17P5TOEU0W0", "设备形式");
|
||||
m.put("TextField_23GWUBGROXWG0", "动载");
|
||||
m.put("TextField_SIM35ICCGOW0", "静载");
|
||||
m.put("TextField_1X4ISVYJ2E000", "电源电压");
|
||||
m.put("TextField_F05H5U3N9NC0", "电压频率是否特殊");
|
||||
m.put("TextField_J84FK4ALUOG0", "减速器要求");
|
||||
m.put("TextField_3IXTW5EOSTK0", "导向形式");
|
||||
m.put("DDSelectField_4JP6PT1HB480", "有无脚轮");
|
||||
m.put("TextField_1ED24R0QOG4G0", "卷筒直径");
|
||||
m.put("TextField_IR0XM2QFI4G0", "吊点数");
|
||||
m.put("TextField_MWLXHEAJYDS0", "额定载荷");
|
||||
m.put("TextField_GZISO77XGU80", "杆体自重/总载荷");
|
||||
m.put("DDSelectField_1XGOO6QI7YE80", "有无载荷传感器");
|
||||
m.put("TextField_V3UBXSM0V400", "箱体形式");
|
||||
m.put("TextField_1N6AOCMUFXXC0", "出轴方式/方向");
|
||||
m.put("TextField_5B1TRAUGUP80", "地脚板位置");
|
||||
m.put("TextField_G2N28LNPOKO0", "行走速度");
|
||||
m.put("DDSelectField_Y8AKWL5T20G0", "是否带升降");
|
||||
m.put("TextField_1X0CJO3BBELC0", "升降高度");
|
||||
m.put("TextField_1DCKMEARM96O0", "升降速度");
|
||||
m.put("DDSelectField_1UNDZ9DNXIN4", "导航方式");
|
||||
m.put("TextField_CO3RY4XTL800", "电机减速机种类");
|
||||
m.put("TextField_QZAR20YC9DC0", "旋转速度");
|
||||
m.put("TextField_1N728V92Z1LS0", "使用频率");
|
||||
m.put("TextareaField_9MIMABZEHW40", "使用环境");
|
||||
m.put("TextareaField_1WLKQPZU8UF40", "电控要求");
|
||||
m.put("TextareaField_1BXA83S0L9Q80", "安装位置(如有纵/横剖图可附件说明)");
|
||||
m.put("TextareaField_15N86B1OM9R40", "其他特殊要求");
|
||||
m.put("TextareaField_ZCRQZCLP3800", "方案补充说明");
|
||||
m.put("ColumnLayout_PV2QMZXXVCW0", "分栏");
|
||||
m.put("DDAttachment_XJYUB17OFGW0", "附件");
|
||||
m.put("TextareaField_GO981AG879K0", "技术总工意见");
|
||||
m.put("DDSelectField_8DWKMBIUJ4S0", "是否为机械标品");
|
||||
m.put("InnerContactField_1GEJYHX8RFQ80", "指定副总工程师");
|
||||
m.put("InnerContactField_1YBPCOGCMBTS0", "指派项目工程师");
|
||||
m.put("DDDateField_15JD56QBNOF40", "预计方案完成日期");
|
||||
m.put("TextareaField_193R557BONZ40", "项目工程师意见");
|
||||
m.put("TextareaField_1DVKJWXCBJ4W0", "任务详情");
|
||||
m.put("DDDateField_LKZDJVPWIHC0", "方案提交日期");
|
||||
m.put("DDSelectField_JZ9OQZY1A000", "是否收到方案");
|
||||
return Collections.unmodifiableMap(m);
|
||||
}
|
||||
}
|
||||
@ -8,8 +8,8 @@ import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 与 event.json formComponentValues(146-843) 及 gen-ding-scheme-wide.mjs 的 IDS 一致。
|
||||
* 表单宽数据写入 {@code wf_values_json}:JSON 的 key 为钉钉控件 id(原始大小写),与 {@code form_label_map} 的 key 一致。
|
||||
* 与当前钉钉模板 {@link DingSchemeFormLabelMap} / form_label_map 一致。
|
||||
* 表单宽数据写入 {@code wf_values_json}:key=控件 id,与 form_label_map 的 key 一致。
|
||||
*/
|
||||
public final class DingSchemeFormWideColumns {
|
||||
|
||||
@ -30,106 +30,60 @@ public final class DingSchemeFormWideColumns {
|
||||
"DDSelectField_1XTHOHPHULNK0",
|
||||
"TextField_1EIAVY538AM80",
|
||||
"ColumnLayout_N0ZDGQT4UJ40",
|
||||
"TextareaField_GO981AG879K0",
|
||||
"InnerContactField_1TXM18E414740",
|
||||
"InnerContactField_SHOIEPZ1X8W0",
|
||||
"DDDateField_1107GY4FF5R40",
|
||||
"TextareaField_1JNZ7QFU4GLC0",
|
||||
"ColumnLayout_5UK9OEEPNQG0",
|
||||
"TextNote_14QFWOA0NXUK",
|
||||
"DDSelectField_JDD37MSAU7K0",
|
||||
"TextField_7KHHS2KML4G0",
|
||||
"TextField_17ONU2GWWQQK0",
|
||||
"TextField_1D66PIGUHPEO0",
|
||||
"TextField_2E68TAT1P2B",
|
||||
"TextField_1FVHYJIFC9340",
|
||||
"DDSelectField_12J1O9KUMFK00",
|
||||
"DDSelectField_1CTHXMP1W6000",
|
||||
"DDSelectField_1QQEC44I00G00",
|
||||
"TextField_1X4ISVYJ2E000",
|
||||
"TextareaField_9MIMABZEHW40",
|
||||
"TextField_1N728V92Z1LS0",
|
||||
"DDSelectField_4JP6PT1HB480",
|
||||
"TextareaField_1WLKQPZU8UF40",
|
||||
"TextareaField_ZCRQZCLP3800",
|
||||
"ColumnLayout_704TMWHBUK00",
|
||||
"DDAttachment_XJYUB17OFGW0",
|
||||
"TextNote_1S3AH8USXUU80",
|
||||
"TextNote_1S2UFGJ55CDC0",
|
||||
"TextField_1JWDW5KVN95S0",
|
||||
"TextField_1CTQW75A6XK00",
|
||||
"TextField_6JT3ARDIUY40",
|
||||
"TextField_1JWDW5KVN95S0",
|
||||
"TextField_17ONU2GWWQQK0",
|
||||
"TextField_2E68TAT1P2B",
|
||||
"TextField_1D66PIGUHPEO0",
|
||||
"DDSelectField_12J1O9KUMFK00",
|
||||
"DDSelectField_1QQEC44I00G00",
|
||||
"TextField_1FVHYJIFC9340",
|
||||
"DDSelectField_1CTHXMP1W6000",
|
||||
"DDSelectField_1J17P5TOEU0W0",
|
||||
"TextField_23GWUBGROXWG0",
|
||||
"TextField_SIM35ICCGOW0",
|
||||
"TextField_18UFLIYK2G0W",
|
||||
"TextField_EEO52079YWG0",
|
||||
"TextField_17J58EEU17DS0",
|
||||
"TextField_1X4ISVYJ2E000",
|
||||
"TextField_F05H5U3N9NC0",
|
||||
"TextField_J84FK4ALUOG0",
|
||||
"TextField_3IXTW5EOSTK0",
|
||||
"ColumnLayout_OWD8CAEIPCW0",
|
||||
"DDAttachment_ZVUJAK8ZRVK0",
|
||||
"TextNote_196NEZF2GKQO0",
|
||||
"TextareaField_1BXA83S0L9Q80",
|
||||
"DDSelectField_1J17P5TOEU0W0",
|
||||
"DDSelectField_4JP6PT1HB480",
|
||||
"TextField_1ED24R0QOG4G0",
|
||||
"TextField_62OWJDX5J780",
|
||||
"TextField_W509DMUVT0W0",
|
||||
"TextField_IR0XM2QFI4G0",
|
||||
"TextField_MWLXHEAJYDS0",
|
||||
"TextField_GZISO77XGU80",
|
||||
"DDSelectField_1XGOO6QI7YE80",
|
||||
"TextareaField_15N86B1OM9R40",
|
||||
"ColumnLayout_13OIS5R5G4G00",
|
||||
"DDAttachment_Y0KM7E71JY80",
|
||||
"TextNote_65FUYS6PMOG0",
|
||||
"TextField_1WOIAN7UXMXS0",
|
||||
"TextField_1B349K9H85FK0",
|
||||
"TextField_V3UBXSM0V400",
|
||||
"TextField_1N6AOCMUFXXC0",
|
||||
"TextField_5B1TRAUGUP80",
|
||||
"DDSelectField_R805UL353UO0",
|
||||
"TextField_210LMWSH8CCG0",
|
||||
"TextareaField_6JU2QSEND4G0",
|
||||
"ColumnLayout_1OBP4JCUUC1S0",
|
||||
"DDAttachment_1OQ414MMSQE80",
|
||||
"TextNote_7USWEJCWOHO0",
|
||||
"TextField_10A0OELOA9CW0",
|
||||
"TextField_1F35DOLS3GJK0",
|
||||
"TextField_G2N28LNPOKO0",
|
||||
"DDSelectField_Y8AKWL5T20G0",
|
||||
"TextField_1X0CJO3BBELC0",
|
||||
"TextField_1DCKMEARM96O0",
|
||||
"TextareaField_8ZYS78VXXKG0",
|
||||
"DDSelectField_1UNDZ9DNXIN4",
|
||||
"TextareaField_902TJ8AC3BO0",
|
||||
"ColumnLayout_1V6324DSHDMO0",
|
||||
"DDAttachment_19GLQ5UABT9C0",
|
||||
"TextNote_1JGD3A0EBOU80",
|
||||
"DDSelectField_JDD37MSAU7K0",
|
||||
"TextField_1ODO49P4QIOW0",
|
||||
"TextField_15YXLN28VYWW0",
|
||||
"TextField_N3EEZETOMLS0",
|
||||
"TextField_MZLNE0WXSYO0",
|
||||
"DDSelectField_1D1NY47OPRY80",
|
||||
"TextField_CO3RY4XTL800",
|
||||
"TextField_1LJRN85YYW680",
|
||||
"TextareaField_1W3YXGM2WVWG0",
|
||||
"ColumnLayout_FVVK6OHVSMO0",
|
||||
"DDAttachment_NISKKTWA4LC0",
|
||||
"TextNote_18NMSNM15JLS0",
|
||||
"TextField_YON75A1BPDS0",
|
||||
"TextField_1LA4D1ZNJCO00",
|
||||
"TextField_QZAR20YC9DC0",
|
||||
"TextField_W5VDI6TJE0W0",
|
||||
"DDSelectField_JQFNCPP9Q8G0",
|
||||
"TextField_X7WT90RW88W0",
|
||||
"TextareaField_XVWU129IDG00",
|
||||
"TextField_21CFZH9VCESG0",
|
||||
"TextareaField_20MIUBGWHAYO0",
|
||||
"ColumnLayout_7E01AAY4TUO0",
|
||||
"DDAttachment_PVHB9480IPS0",
|
||||
"TextareaField_I623WTCGKBK0",
|
||||
"DDDateField_1QY4LG6SI9FK0",
|
||||
"DDSelectField_W8ZTK2TQHHS0"
|
||||
"TextField_1N728V92Z1LS0",
|
||||
"TextareaField_9MIMABZEHW40",
|
||||
"TextareaField_1WLKQPZU8UF40",
|
||||
"TextareaField_1BXA83S0L9Q80",
|
||||
"TextareaField_15N86B1OM9R40",
|
||||
"TextareaField_ZCRQZCLP3800",
|
||||
"ColumnLayout_PV2QMZXXVCW0",
|
||||
"DDAttachment_XJYUB17OFGW0",
|
||||
"TextareaField_GO981AG879K0",
|
||||
"DDSelectField_8DWKMBIUJ4S0",
|
||||
"InnerContactField_1GEJYHX8RFQ80",
|
||||
"ColumnLayout_1P00KI5NCBKW0",
|
||||
"InnerContactField_1YBPCOGCMBTS0",
|
||||
"DDDateField_15JD56QBNOF40",
|
||||
"TextareaField_193R557BONZ40",
|
||||
"ColumnLayout_1C721C2ID5PC0",
|
||||
"TextareaField_1DVKJWXCBJ4W0",
|
||||
"DDDateField_LKZDJVPWIHC0",
|
||||
"DDSelectField_JZ9OQZY1A000"
|
||||
));
|
||||
|
||||
private static final Set<String> ID_SET = new HashSet<>(ORDERED_IDS);
|
||||
@ -138,12 +92,10 @@ public final class DingSchemeFormWideColumns {
|
||||
return componentId != null && ID_SET.contains(componentId);
|
||||
}
|
||||
|
||||
/** JSON 中的控件 id key(与钉钉一致) */
|
||||
public static String jsonKey(String componentId) {
|
||||
return componentId;
|
||||
}
|
||||
|
||||
/** 兼容旧「列名」思路:wf_ + id 小写,仅用于文档/SQL 排查,不再建物理列 */
|
||||
public static String legacyPhysicalColumnName(String componentId) {
|
||||
return "wf_" + componentId.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
@ -0,0 +1,195 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
/**
|
||||
* 钉钉控件 id({@link DingSchemeFormLabelMap})→ PLM {@code sales/saleplanapplyform} 字段。
|
||||
* 仅包含当前 form_label_map 中存在的控件;注释为钉钉中文标题。
|
||||
* <p>
|
||||
* 「刚性链类型」→ PLM {@code gxllx}(string,多选逗号拼接)。
|
||||
* 「指派的副总工程师」→ PLM {@code zpdfzgcs}(string 工号):按钉钉姓名映射,见 {@link DingSchemeDeputyChiefNameMap}。
|
||||
* </p>
|
||||
*/
|
||||
public final class DingSchemePlmFieldIds {
|
||||
|
||||
private DingSchemePlmFieldIds() {
|
||||
}
|
||||
|
||||
/** 方案申请编号 → fasqbh */
|
||||
public static final String SCHEME_APPLY_NO = "TextField_1BBYI1OFDJA80";
|
||||
|
||||
/** 概述名称 → gsmc */
|
||||
public static final String OVERVIEW_NAME = "TextField_FRLYG3CQ3CG0";
|
||||
|
||||
/** 填表人 → tbr */
|
||||
public static final String FILLER = "InnerContactField_9DSIOI7Y7AO0";
|
||||
|
||||
/** 填表日期 → tbrq */
|
||||
public static final String FILL_DATE = "DDDateField_1BHYQ7T5N5TS0";
|
||||
|
||||
/** 需求日期 → xqrq */
|
||||
public static final String NEED_DATE = "DDDateField_YYD1HAMKFXS0";
|
||||
|
||||
/** 有无前期对接工程师 */
|
||||
public static final String HAS_EARLY_ENGINEER = "DDSelectField_1VS1BX17O9MO0";
|
||||
|
||||
/** 前期对接工程师 → qqdjgcs(多选姓名逗号拼接) */
|
||||
public static final String EARLY_ENGINEER = "InnerContactField_U886PC45AO00";
|
||||
|
||||
/** 客户全称 → khgsqc */
|
||||
public static final String CUSTOMER = "TextField_1HXMC0VO5TCW0";
|
||||
|
||||
/** 联系人及电话 → lxrjdh */
|
||||
public static final String CONTACT = "TextField_QBMQQBNCTA80";
|
||||
|
||||
/** 项目分类 */
|
||||
public static final String PROJECT_CATEGORY = "DDSelectField_845RKMRCBNC";
|
||||
|
||||
/** 产品名称 → cpmc */
|
||||
public static final String PRODUCT_NAME = "DDSelectField_1XTHOHPHULNK0";
|
||||
|
||||
/** 产品应用领域 → cpyyly */
|
||||
public static final String PRODUCT_DOMAIN = "TextField_1EIAVY538AM80";
|
||||
|
||||
/** 分栏 */
|
||||
public static final String COLUMN_LAYOUT_MAIN = "ColumnLayout_N0ZDGQT4UJ40";
|
||||
|
||||
/** 刚性链类型 → gxllx */
|
||||
public static final String RIGID_CHAIN_TYPE = "DDSelectField_JDD37MSAU7K0";
|
||||
|
||||
/** 台面尺寸 → tmcc */
|
||||
public static final String TABLE_SIZE = "TextField_7KHHS2KML4G0";
|
||||
|
||||
/** 台面尺寸/外形轮廓 → tmccwxlk */
|
||||
public static final String TABLE_OUTLINE = "TextField_1CTQW75A6XK00";
|
||||
|
||||
/** 外形尺寸(长宽高) → wxcc */
|
||||
public static final String OUTLINE_SIZE = "TextField_6JT3ARDIUY40";
|
||||
|
||||
/** 基坑深度 → jksd */
|
||||
public static final String PIT_DEPTH = "TextField_1JWDW5KVN95S0";
|
||||
|
||||
/** 行程 → xc */
|
||||
public static final String STROKE = "TextField_17ONU2GWWQQK0";
|
||||
|
||||
/** 速度(单位:m/s或mm/s) → sd */
|
||||
public static final String SPEED = "TextField_2E68TAT1P2B";
|
||||
|
||||
/** 负载(单位:kg) → fz */
|
||||
public static final String LOAD = "TextField_1D66PIGUHPEO0";
|
||||
|
||||
/** 驱动方式 → qdfs */
|
||||
public static final String DRIVE_MODE = "DDSelectField_12J1O9KUMFK00";
|
||||
|
||||
/** 限位方式 → xwfs */
|
||||
public static final String LIMIT_MODE = "DDSelectField_1QQEC44I00G00";
|
||||
|
||||
/** 最低高度 → zdgd */
|
||||
public static final String MIN_HEIGHT = "TextField_1FVHYJIFC9340";
|
||||
|
||||
/** 有无偏载 → ywpz */
|
||||
public static final String ECCENTRIC_LOAD = "DDSelectField_1CTHXMP1W6000";
|
||||
|
||||
/** 设备形式 → sbxs */
|
||||
public static final String DEVICE_FORM = "DDSelectField_1J17P5TOEU0W0";
|
||||
|
||||
/** 动载 → dz */
|
||||
public static final String DYNAMIC_LOAD = "TextField_23GWUBGROXWG0";
|
||||
|
||||
/** 静载 → jz */
|
||||
public static final String STATIC_LOAD = "TextField_SIM35ICCGOW0";
|
||||
|
||||
/** 电源电压 → dydy */
|
||||
public static final String VOLTAGE = "TextField_1X4ISVYJ2E000";
|
||||
|
||||
/** 电压频率是否特殊 → dyplsfts */
|
||||
public static final String VOLTAGE_FREQ_SPECIAL = "TextField_F05H5U3N9NC0";
|
||||
|
||||
/** 减速器要求 → jsqyq */
|
||||
public static final String REDUCER_REQ = "TextField_J84FK4ALUOG0";
|
||||
|
||||
/** 导向形式 → dxxs */
|
||||
public static final String GUIDE_FORM = "TextField_3IXTW5EOSTK0";
|
||||
|
||||
/** 有无脚轮 → ywjl */
|
||||
public static final String CASTERS = "DDSelectField_4JP6PT1HB480";
|
||||
|
||||
/** 卷筒直径 → jtzj */
|
||||
public static final String DRUM_DIAMETER = "TextField_1ED24R0QOG4G0";
|
||||
|
||||
/** 吊点数 → dds */
|
||||
public static final String LIFT_POINTS = "TextField_IR0XM2QFI4G0";
|
||||
|
||||
/** 额定载荷 → edzh */
|
||||
public static final String RATED_LOAD = "TextField_MWLXHEAJYDS0";
|
||||
|
||||
/** 杆体自重/总载荷 → gtzz */
|
||||
public static final String ROD_WEIGHT = "TextField_GZISO77XGU80";
|
||||
|
||||
/** 有无载荷传感器 → ywzhcgq */
|
||||
public static final String LOAD_SENSOR = "DDSelectField_1XGOO6QI7YE80";
|
||||
|
||||
/** 箱体形式 → xtxs */
|
||||
public static final String BOX_FORM = "TextField_V3UBXSM0V400";
|
||||
|
||||
/** 出轴方式/方向 → czfsfx */
|
||||
public static final String SHAFT_MODE = "TextField_1N6AOCMUFXXC0";
|
||||
|
||||
/** 地脚板位置 → djbwz */
|
||||
public static final String FOOT_PLATE_POS = "TextField_5B1TRAUGUP80";
|
||||
|
||||
/** 行走速度 → xingzsd */
|
||||
public static final String TRAVEL_SPEED = "TextField_G2N28LNPOKO0";
|
||||
|
||||
/** 是否带升降 → sfdjs */
|
||||
public static final String WITH_LIFT = "DDSelectField_Y8AKWL5T20G0";
|
||||
|
||||
/** 升降高度 → sjgd */
|
||||
public static final String LIFT_HEIGHT = "TextField_1X0CJO3BBELC0";
|
||||
|
||||
/** 升降速度 → sjsd */
|
||||
public static final String LIFT_SPEED = "TextField_1DCKMEARM96O0";
|
||||
|
||||
/** 导航方式 → dhfs */
|
||||
public static final String NAV_MODE = "DDSelectField_1UNDZ9DNXIN4";
|
||||
|
||||
/** 电机减速机种类 → djjsjzl */
|
||||
public static final String MOTOR_REDUCER_TYPE = "TextField_CO3RY4XTL800";
|
||||
|
||||
/** 旋转速度 → xuanzsd */
|
||||
public static final String ROTATE_SPEED = "TextField_QZAR20YC9DC0";
|
||||
|
||||
/** 使用频率 → sypl */
|
||||
public static final String FREQ = "TextField_1N728V92Z1LS0";
|
||||
|
||||
/** 使用环境 → syhj */
|
||||
public static final String ENV = "TextareaField_9MIMABZEHW40";
|
||||
|
||||
/** 电控要求 → dkyq */
|
||||
public static final String ELECTRIC_REQ = "TextareaField_1WLKQPZU8UF40";
|
||||
|
||||
/** 安装位置(如有纵/横剖图可附件说明) → azwz */
|
||||
public static final String INSTALL_POS = "TextareaField_1BXA83S0L9Q80";
|
||||
|
||||
/** 其他特殊要求 → qttsyq */
|
||||
public static final String OTHER_SPECIAL = "TextareaField_15N86B1OM9R40";
|
||||
|
||||
/** 方案补充说明 → fapcsm */
|
||||
public static final String SCHEME_NOTE = "TextareaField_ZCRQZCLP3800";
|
||||
|
||||
/** 分栏 */
|
||||
public static final String COLUMN_LAYOUT_ATTACH = "ColumnLayout_PV2QMZXXVCW0";
|
||||
|
||||
/** 附件 */
|
||||
public static final String ATTACHMENT_MAIN = "DDAttachment_XJYUB17OFGW0";
|
||||
|
||||
/** 技术总工意见 → jszgyj */
|
||||
public static final String CHIEF_ENGINEER_OPINION = "TextareaField_GO981AG879K0";
|
||||
|
||||
/** 是否为机械标品(是 → zpdfzgcs 固定 00026) */
|
||||
public static final String MECHANICAL_STANDARD_PRODUCT = "DDSelectField_8DWKMBIUJ4S0";
|
||||
|
||||
/** 项目负责副总工程师 / 指定副总工程师 → zpdfzgcs(姓名映射工号) */
|
||||
public static final String ASSIGNED_DEPUTY_CHIEF = "InnerContactField_1GEJYHX8RFQ80";
|
||||
|
||||
/** 旧版表单控件 id(兼容历史 wf_values_json) */
|
||||
public static final String ASSIGNED_DEPUTY_CHIEF_LEGACY = "InnerContactField_1TXM18E414740";
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PLM {@code sales/saleplanapplyform} 全部表单字段名。
|
||||
* 非必填字段也必须传参,无值时传空字符串 {@code ""},不能缺 key 或传 null。
|
||||
*/
|
||||
public final class DingSchemePlmFormKeys {
|
||||
|
||||
private DingSchemePlmFormKeys() {
|
||||
}
|
||||
|
||||
public static final List<String> ALL = Collections.unmodifiableList(Arrays.asList(
|
||||
"fasqbh", "mc", "gsmc", "tbr", "tbrq", "xqrq", "khgsqc", "lxrjdh",
|
||||
"cpmc", "cpyyly", "tmcc", "xc", "zdgd", "qdfs", "ywpz", "xwfs",
|
||||
"dydy", "syhj", "sypl", "ywjl", "dkyq", "fapcsm", "jksd", "dz", "jz",
|
||||
"dyplsfts", "jsqyq", "dxxs", "azwz", "sbxs", "jtzj", "dds", "edzh",
|
||||
"gtzz", "ywzhcgq", "xtxs", "czfsfx", "djbwz", "sfdjs", "sjgd", "sjsd",
|
||||
"dhfs", "gxllx", "djjsjzl", "sd", "tsxc", "tssd", "tmccwxlk", "wxcc",
|
||||
"fz", "xingzsd", "xuanzsd", "jszgyj", "zpdfzgcs", "qqdjgcs", "qttsyq"
|
||||
));
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
/**
|
||||
* 项目令号 {@code process_order_pro.source} 来源。
|
||||
*/
|
||||
public final class ProcessOrderProSource {
|
||||
|
||||
/** 页面/接口手工新增 */
|
||||
public static final String MANUAL = "手动";
|
||||
|
||||
/** PLM 等外部系统同步 */
|
||||
public static final String PLM = "PLM";
|
||||
|
||||
private ProcessOrderProSource() {
|
||||
}
|
||||
|
||||
public static boolean isValid(String source) {
|
||||
return MANUAL.equals(source) || PLM.equals(source);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.system.constant;
|
||||
|
||||
/**
|
||||
* 采购订单审批待办钉钉提醒:审批人姓名与 StaffId 映射(写死在代码中)。
|
||||
*/
|
||||
public final class PurchaseOrderApproverNotifyConstants {
|
||||
|
||||
private PurchaseOrderApproverNotifyConstants() {
|
||||
}
|
||||
|
||||
/** 刘冉 钉钉 StaffId */
|
||||
public static final String LIU_RAN_STAFF_ID = "010858214800672369";
|
||||
|
||||
/** 张敏 钉钉 StaffId */
|
||||
public static final String ZHANG_MIN_STAFF_ID = "1017253114780847";
|
||||
|
||||
/** 默认抄送(任务执行汇总,用于确认推送是否成功) */
|
||||
public static final String DEFAULT_NOTIFY_STAFF_ID = "283633411029629036";
|
||||
|
||||
/** 工作流当前审批人姓名匹配:刘冉 */
|
||||
public static final String LIU_RAN_NAME = "刘冉";
|
||||
|
||||
/** 工作流当前审批人姓名匹配:张敏(金蝶工作流中的真实姓名) */
|
||||
public static final String ZHANG_MIN_NAME = "张敏";
|
||||
|
||||
/** 钉钉推送展示称呼:张总 */
|
||||
public static final String ZHANG_MIN_DISPLAY_NAME = "张总";
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.dto.productionorder.AssemblyBomReceiveItemDTO;
|
||||
import com.ruoyi.system.domain.dto.productionorder.AssemblyBomReceiveSummary;
|
||||
import com.ruoyi.system.service.IPlmReceiveLogService;
|
||||
import com.ruoyi.system.service.IProductionOrderService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PLM 总装配 BOM 推送接收入口(POST JSON 数组)。
|
||||
*/
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/plm")
|
||||
public class AssemblyBomReceiveController extends BaseController {
|
||||
|
||||
private static final String API_PATH = "/system/plm/assemblyBomReceive";
|
||||
|
||||
private final IProductionOrderService productionOrderService;
|
||||
private final IPlmReceiveLogService plmReceiveLogService;
|
||||
|
||||
/**
|
||||
* 接收总装配 BOM 行列表,按生产令号全量替换写入 production_order,并同步 bom_details(bomType=0)。
|
||||
* <p>
|
||||
* POST /system/plm/assemblyBomReceive<br>
|
||||
* Content-Type: application/json; charset=UTF-8
|
||||
*/
|
||||
@SaIgnore
|
||||
@Log(title = "总装配BOM推送接收", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/assemblyBomReceive")
|
||||
public R<AssemblyBomReceiveSummary> receive(@Valid @RequestBody List<AssemblyBomReceiveItemDTO> body) {
|
||||
String payloadJson = JSON.toJSONString(body);
|
||||
String orderNo = resolveOrderNo(body);
|
||||
String clientIp = resolveClientIp();
|
||||
try {
|
||||
AssemblyBomReceiveSummary summary = productionOrderService.receiveAssemblyBom(body);
|
||||
Map<String, Object> summaryMap = new LinkedHashMap<>();
|
||||
summaryMap.put("productionOrderNo", summary.getProductionOrderNo());
|
||||
summaryMap.put("lineCount", summary.getLineCount());
|
||||
summaryMap.put("insertedCount", summary.getInsertedCount());
|
||||
summaryMap.put("replaced", summary.isReplaced());
|
||||
plmReceiveLogService.record(
|
||||
IPlmReceiveLogService.BIZ_ASSEMBLY_BOM,
|
||||
API_PATH,
|
||||
summary.getProductionOrderNo(),
|
||||
payloadJson,
|
||||
JSON.toJSONString(summaryMap),
|
||||
summary.getLineCount(),
|
||||
summary.getInsertedCount(),
|
||||
summary.isReplaced(),
|
||||
IPlmReceiveLogService.STATUS_SUCCESS,
|
||||
null,
|
||||
clientIp
|
||||
);
|
||||
return R.ok("接收成功", summary);
|
||||
} catch (Exception e) {
|
||||
plmReceiveLogService.record(
|
||||
IPlmReceiveLogService.BIZ_ASSEMBLY_BOM,
|
||||
API_PATH,
|
||||
orderNo,
|
||||
payloadJson,
|
||||
null,
|
||||
body == null ? 0 : body.size(),
|
||||
null,
|
||||
null,
|
||||
IPlmReceiveLogService.STATUS_FAIL,
|
||||
e.getMessage(),
|
||||
clientIp
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static String resolveOrderNo(List<AssemblyBomReceiveItemDTO> body) {
|
||||
if (body == null) {
|
||||
return null;
|
||||
}
|
||||
for (AssemblyBomReceiveItemDTO item : body) {
|
||||
if (item != null && StringUtils.isNotBlank(item.getProductionOrderNo())) {
|
||||
return item.getProductionOrderNo().trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String resolveClientIp() {
|
||||
try {
|
||||
return ServletUtils.getClientIP();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,9 +29,11 @@ import com.ruoyi.common.config.DingTalkProperties;
|
||||
import com.ruoyi.common.dingding.util.DingUtil;
|
||||
import com.ruoyi.common.utils.JdUtils;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.constant.ProcessOrderProSource;
|
||||
import com.ruoyi.system.domain.BomDetails;
|
||||
import com.ruoyi.system.domain.MaterialProperties;
|
||||
import com.ruoyi.system.domain.ProcessOrderPro;
|
||||
import com.ruoyi.system.domain.ProductionOrder;
|
||||
import com.ruoyi.system.domain.bo.BomDetailsBo;
|
||||
import com.ruoyi.system.domain.vo.BomDetailsVo;
|
||||
import com.ruoyi.system.domain.vo.ElectricalMaterialBomVO;
|
||||
@ -84,7 +86,7 @@ public class BomDetailsController extends BaseController {
|
||||
|
||||
private final IProcessOrderProService iProcessOrderProService;
|
||||
|
||||
private final IProductionOrderService iProductionOrderService;
|
||||
private final IProductionOrderService iProductionOrderService;
|
||||
|
||||
private final ProcessOrderProMapper processOrderProMapper;
|
||||
|
||||
@ -107,15 +109,18 @@ public class BomDetailsController extends BaseController {
|
||||
List<BomDetailsVo> topLevelList = new ArrayList<>();
|
||||
List<BomDetailsVo> rows = bomDetailsVoTableDataInfo.getRows();
|
||||
for (BomDetailsVo bomDetailsVo : rows) {
|
||||
String parentCodeAndName = String.format("%s_%s", bomDetailsVo.getFName(), bomDetailsVo.getFNumber());
|
||||
String assemblyCode = resolveAssemblyCode(bomDetailsVo);
|
||||
String parentCodeAndName = String.format("%s_%s", bomDetailsVo.getFName(), assemblyCode);
|
||||
BomDetailsVo parent = bomMap.get(parentCodeAndName);
|
||||
if (parent == null) {
|
||||
parent = new BomDetailsVo();
|
||||
parent.setId(generateUniqueParentId(bomDetailsVo.getId()));
|
||||
// parent.setUnitWeight(bomDetailsVo.getUnitWeight());
|
||||
parent.setParentCodeAndName(parentCodeAndName);
|
||||
parent.setFNumber(bomDetailsVo.getFNumber());
|
||||
parent.setFNumber(assemblyCode);
|
||||
parent.setFName(bomDetailsVo.getFName());
|
||||
parent.setPartdiagramCode(bomDetailsVo.getPartdiagramCode());
|
||||
parent.setPartdiagramName(bomDetailsVo.getPartdiagramName());
|
||||
parent.setUnitWeight(bomDetailsVo.getUnitWeight());
|
||||
parent.setStats(bomDetailsVo.getStats());
|
||||
parent.setMaterial(bomDetailsVo.getMaterial());
|
||||
@ -142,21 +147,90 @@ public class BomDetailsController extends BaseController {
|
||||
return originalId + 1000;
|
||||
}
|
||||
|
||||
/** 总成物料编码:优先 f_number,其次 partdiagram_code(装备 BOM 导入常缺 f_number) */
|
||||
private String resolveAssemblyCode(BomDetailsVo vo) {
|
||||
if (vo == null) {
|
||||
return "";
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getFNumber())) {
|
||||
return vo.getFNumber().trim();
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getPartdiagramCode())) {
|
||||
return vo.getPartdiagramCode().trim();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void normalizeAssemblyFNumber(List<BomDetails> bomDetails, String assemblyCode) {
|
||||
if (bomDetails == null || bomDetails.isEmpty() || StringUtils.isBlank(assemblyCode)) {
|
||||
return;
|
||||
}
|
||||
for (BomDetails row : bomDetails) {
|
||||
if (StringUtils.isBlank(row.getFNumber())) {
|
||||
row.setFNumber(assemblyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 父级物料 f_number 建档:仅使用 bom_details.dan_zhong,不再查其它表。
|
||||
*/
|
||||
private void writeKingdeeParentDanZhong(JsonObject model, BomDetails row, String scene) {
|
||||
if (row == null || StringUtils.isBlank(row.getFNumber())) {
|
||||
log.info("[金蝶单重上传] {} | 父级 | FNumber=空 | F_HBYT_DZ=未写入 | 来源=无", scene);
|
||||
return;
|
||||
}
|
||||
String fNumber = row.getFNumber().trim();
|
||||
String fName = row.getFName() != null ? row.getFName() : "";
|
||||
Double dz = row.getDanZhong();
|
||||
String source = dz != null ? "bom_details.dan_zhong" : "无";
|
||||
log.info("[金蝶单重上传] {} | 父级 | FNumber={} | FName={} | F_HBYT_DZ={} | 来源={}",
|
||||
scene, fNumber, fName, dz != null ? dz : "未写入", source);
|
||||
if (dz != null) {
|
||||
model.addProperty("F_HBYT_DZ", dz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 子项物料 part_number 建档:仅使用 bom_details.single_weghit,不再查其它表。
|
||||
*/
|
||||
private void writeKingdeeChildDanZhong(JsonObject model, BomDetails row, String scene) {
|
||||
if (row == null || StringUtils.isBlank(row.getPartNumber())) {
|
||||
log.info("[金蝶单重上传] {} | 子项 | FNumber=空 | F_HBYT_DZ=未写入 | 来源=无", scene);
|
||||
return;
|
||||
}
|
||||
String partNumber = row.getPartNumber().trim();
|
||||
String name = row.getName() != null ? row.getName() : "";
|
||||
Double dz = row.getSingleWeghit();
|
||||
String source = dz != null ? "bom_details.single_weghit" : "无";
|
||||
log.info("[金蝶单重上传] {} | 子项 | FNumber={} | FName={} | F_HBYT_DZ={} | 来源={}",
|
||||
scene, partNumber, name, dz != null ? dz : "未写入", source);
|
||||
if (dz != null) {
|
||||
model.addProperty("F_HBYT_DZ", dz);
|
||||
}
|
||||
}
|
||||
|
||||
private BomDetailsVo createChildVo(BomDetailsVo bomDetailsVo) {
|
||||
BomDetailsVo child = null;
|
||||
child = new BomDetailsVo();
|
||||
BomDetailsVo child = new BomDetailsVo();
|
||||
child.setId(bomDetailsVo.getId());
|
||||
child.setTotalWeight(bomDetailsVo.getTotalWeight());
|
||||
child.setFNumber(resolveAssemblyCode(bomDetailsVo));
|
||||
child.setFName(bomDetailsVo.getFName());
|
||||
child.setPartNumber(bomDetailsVo.getPartNumber());
|
||||
child.setName(bomDetailsVo.getName());
|
||||
child.setPartdiagramCode(bomDetailsVo.getPartdiagramCode());
|
||||
child.setPartdiagramName(bomDetailsVo.getPartdiagramName());
|
||||
child.setQuantity(bomDetailsVo.getQuantity());
|
||||
child.setDenominator(bomDetailsVo.getDenominator());
|
||||
child.setStats(bomDetailsVo.getStats());
|
||||
child.setMaterial(bomDetailsVo.getMaterial());
|
||||
child.setRemarks(bomDetailsVo.getRemarks());
|
||||
// child.setTotalWeight(bomDetailsVo.getTotalWeight());
|
||||
child.setWareHouse(bomDetailsVo.getWareHouse());
|
||||
child.setUnitWeight(bomDetailsVo.getUnitWeight());
|
||||
|
||||
// 其他必要的字段赋值
|
||||
child.setDanZhong(bomDetailsVo.getDanZhong());
|
||||
child.setSingleWeghit(bomDetailsVo.getSingleWeghit());
|
||||
child.setBomType(bomDetailsVo.getBomType());
|
||||
child.setStateImportance(bomDetailsVo.getStateImportance());
|
||||
child.setRemarks(bomDetailsVo.getRemarks());
|
||||
return child;
|
||||
}
|
||||
|
||||
@ -331,9 +405,7 @@ public class BomDetailsController extends BaseController {
|
||||
* @return
|
||||
*/
|
||||
public static String determineState(BomDetails stats) {
|
||||
if (stats == null || stats.getStats().equals("外购") || stats.getFName().startsWith("009") ||
|
||||
stats.getFName().startsWith("AA") || stats.getFName().startsWith("AB")
|
||||
|| stats.getFName().startsWith("AC")) {
|
||||
if (stats == null || stats.getStats().equals("外购") || stats.getFName().startsWith("009") || stats.getFName().startsWith("AA") || stats.getFName().startsWith("AB") || stats.getFName().startsWith("AC")) {
|
||||
return "1";
|
||||
} else if (stats.getStats().equals("自制")) {
|
||||
return "2";
|
||||
@ -343,6 +415,28 @@ public class BomDetailsController extends BaseController {
|
||||
return "1";
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否走生产物料建档(与总装一致)。
|
||||
* <ul>
|
||||
* <li>bomType=0 总装 → 生产建档</li>
|
||||
* <li>PLM 项目 / PLM 推送的材料 BOM(bomType=1)→ 生产建档(按 stats 写自制/外购)</li>
|
||||
* <li>仅非 PLM 的电气 Excel BOM(bomType=1)→ 电气建档</li>
|
||||
* </ul>
|
||||
*/
|
||||
private static boolean useProductionMaterialSave(BomDetails material, ProcessOrderPro project) {
|
||||
if (material == null) {
|
||||
return true;
|
||||
}
|
||||
if ("0".equals(material.getBomType())) {
|
||||
return true;
|
||||
}
|
||||
if (project != null && ProcessOrderProSource.PLM.equals(project.getSource())) {
|
||||
return true;
|
||||
}
|
||||
return "PLM".equalsIgnoreCase(material.getCreateBy())
|
||||
|| "PLM".equalsIgnoreCase(material.getUpdateBy());
|
||||
}
|
||||
|
||||
/* 触发金蝶物料清单按钮 */
|
||||
@Log(title = "金蝶物料清单更新")
|
||||
@SaCheckPermission("system:details:updateMaterial")
|
||||
@ -376,22 +470,41 @@ public class BomDetailsController extends BaseController {
|
||||
@SaCheckPermission("system:details:updateFBMaterial")
|
||||
@PostMapping("/updateFBMaterial")
|
||||
public R updateFBMaterial(@RequestBody List<Map<String, String>> bomDetailParams) {
|
||||
if (bomDetailParams == null || bomDetailParams.isEmpty()) {
|
||||
return R.fail("请先选择要上传的物料");
|
||||
}
|
||||
List<BomDetails> bomDetailsList = new ArrayList<>();
|
||||
List<KindegeeLogDTO> logDTOS = new ArrayList<>();
|
||||
List<String> failedMaterials = new ArrayList<>(); // 用于跟踪处理失败的物料
|
||||
String totalWeight = "";
|
||||
// 遍历前端传来的数据
|
||||
for (Map<String, String> param : bomDetailParams) {
|
||||
String fnumber = param.get("fnumber"); // 物料编码
|
||||
String groupName = param.get("groupName"); // 物料编码
|
||||
String fnumber = param.get("fnumber"); // 总成物料编码(父项图号)
|
||||
String fname = param.get("fname"); // 总成名称(父项名称)
|
||||
String groupName = param.get("groupName"); // 上传分组
|
||||
totalWeight = param.get("totalWeight"); // 生产令号
|
||||
|
||||
// 根据物料编码和生产令号查询
|
||||
List<BomDetails> bomDetails = iBomDetailsService.selectByFNumberAndTotalWeight(fnumber, totalWeight);
|
||||
log.info("处理物料编码: {}, 生产令号: {}", fnumber, totalWeight);
|
||||
List<BomDetails> bomDetails = null;
|
||||
if (StringUtils.isNotBlank(fnumber)) {
|
||||
bomDetails = iBomDetailsService.selectByFNumberAndTotalWeight(fnumber, totalWeight);
|
||||
}
|
||||
|
||||
if (bomDetails != null && !bomDetails.isEmpty()) {
|
||||
String assemblyCode = StringUtils.isNotBlank(fnumber) ? fnumber : resolveAssemblyCode(BeanUtil.toBean(bomDetails.get(0), BomDetailsVo.class));
|
||||
normalizeAssemblyFNumber(bomDetails, assemblyCode);
|
||||
if (StringUtils.isBlank(fnumber)) {
|
||||
fnumber = assemblyCode;
|
||||
}
|
||||
}
|
||||
log.info("处理物料编码: {}, 总成名称: {}, 生产令号: {}", fnumber, fname, totalWeight);
|
||||
if (bomDetails != null && !bomDetails.isEmpty()) {
|
||||
//TODO 处理父级物料
|
||||
ProcessOrderPro bo = iProcessOrderProService.selectByProjectNumber(totalWeight);
|
||||
if (bo == null) {
|
||||
log.error("未找到生产令号对应的项目, 令号: {}", totalWeight);
|
||||
failedMaterials.add(fnumber);
|
||||
continue;
|
||||
}
|
||||
// 第一步:处理所有物料的保存
|
||||
for (BomDetails material : bomDetails) {
|
||||
// 获取工艺表中的非委外工时
|
||||
@ -404,33 +517,19 @@ public class BomDetailsController extends BaseController {
|
||||
continue;
|
||||
}
|
||||
String state = determineState(material);
|
||||
//判断bom类型是生产还是电气
|
||||
if (material.getBomType().equals("0")) {
|
||||
try {
|
||||
int result = loadMaterialPreservation(material, state, fbWorkTime);
|
||||
if (result == 1) {
|
||||
material.setUnitWeight("新增成功");
|
||||
} else {
|
||||
failedMaterials.add(material.getPartNumber());
|
||||
}
|
||||
// 更新物料状态
|
||||
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
|
||||
} catch (Exception e) {
|
||||
failedMaterials.add(material.getPartNumber());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
int result = loadMaterialToDQ(material, state);
|
||||
if (result == 1) {
|
||||
material.setUnitWeight("新增成功");
|
||||
} else {
|
||||
failedMaterials.add(material.getPartNumber());
|
||||
}
|
||||
// 更新物料状态
|
||||
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
|
||||
} catch (Exception e) {
|
||||
// 总装(bomType=0)与 PLM 工艺材料BOM(bomType=1)均走生产建档;仅非 PLM 的电气 BOM 走电气建档
|
||||
try {
|
||||
int result = useProductionMaterialSave(material, bo)
|
||||
? loadMaterialPreservation(material, state, fbWorkTime)
|
||||
: loadMaterialToDQ(material, state);
|
||||
if (result == 1) {
|
||||
material.setUnitWeight("新增成功");
|
||||
} else {
|
||||
failedMaterials.add(material.getPartNumber());
|
||||
}
|
||||
iBomDetailsService.updateByBo(BeanUtil.toBean(material, BomDetailsBo.class));
|
||||
} catch (Exception e) {
|
||||
failedMaterials.add(material.getPartNumber());
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -476,8 +575,14 @@ public class BomDetailsController extends BaseController {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(totalWeight)) {
|
||||
return R.fail("生产令号不能为空");
|
||||
}
|
||||
//更新项目进度
|
||||
ProcessOrderPro processOrderProBo = iProcessOrderProService.selectByProjectNumber(totalWeight);
|
||||
if (processOrderProBo == null) {
|
||||
return R.fail("未找到生产令号对应的项目: " + totalWeight);
|
||||
}
|
||||
processOrderProBo.setDrawingType(JSONUtil.toJsonStr(logDTOS));
|
||||
processOrderProBo.setBomStatus(2L);
|
||||
processOrderProMapper.updateById(processOrderProBo);
|
||||
@ -835,6 +940,9 @@ public class BomDetailsController extends BaseController {
|
||||
JsonArray fTreeEntity = new JsonArray();
|
||||
model.add("FTreeEntity", fTreeEntity);
|
||||
List<JsonObject> fTreeEntityList = new ArrayList<>();
|
||||
// PLM 总装:production_order.prtType=伊特 与 Excel 备注「伊特」同口径 → FSupplyType=C(采购)
|
||||
String orderNo = bo != null ? bo.getProductionOrderNo() : bomDetails1.getTotalWeight();
|
||||
Set<String> yiteDrawingNos = loadYiteDrawingNosFromProductionOrder(orderNo);
|
||||
for (BomDetails details : bomlist) {
|
||||
if (bomlist.isEmpty()) {
|
||||
return null;
|
||||
@ -855,8 +963,10 @@ public class BomDetailsController extends BaseController {
|
||||
if (iProcessRouteService.isAnTuDingGou(partNumber)) {
|
||||
supplyType = "C";
|
||||
}
|
||||
// 检查是否为伊特
|
||||
else if ("伊特".equals(remarks)) {
|
||||
// 伊特:Excel 备注 / 材质含伊特 / PLM prtType=伊特
|
||||
else if (isYiteText(remarks)
|
||||
|| isYiteText(details.getMaterial())
|
||||
|| yiteDrawingNos.contains(partNumber)) {
|
||||
supplyType = "C";
|
||||
}
|
||||
}
|
||||
@ -912,6 +1022,33 @@ public class BomDetailsController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 production_order 收集 prtType/备注/材质为「伊特」的子项图号(PLM 总装推送口径)。
|
||||
*/
|
||||
private Set<String> loadYiteDrawingNosFromProductionOrder(String productionOrderNo) {
|
||||
Set<String> result = new HashSet<>();
|
||||
if (StringUtils.isBlank(productionOrderNo)) {
|
||||
return result;
|
||||
}
|
||||
List<ProductionOrder> orders = iProductionOrderService.selectByProCode(productionOrderNo);
|
||||
if (orders == null || orders.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
for (ProductionOrder order : orders) {
|
||||
if (order == null || StringUtils.isBlank(order.getDrawingNo())) {
|
||||
continue;
|
||||
}
|
||||
if (isYiteText(order.getPrtType()) || isYiteText(order.getRemark()) || isYiteText(order.getMaterial())) {
|
||||
result.add(order.getDrawingNo().trim());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isYiteText(String text) {
|
||||
return StringUtils.isNotBlank(text) && ("伊特".equals(text.trim()) || text.contains("伊特"));
|
||||
}
|
||||
|
||||
/*
|
||||
* 父级物料保存接口
|
||||
* 单位 是台
|
||||
@ -935,20 +1072,7 @@ public class BomDetailsController extends BaseController {
|
||||
JsonObject FSVRIAssistant = new JsonObject();
|
||||
FSVRIAssistant.addProperty("FNumber", materialProperties.getMaterialAttributeId());
|
||||
model.add("F_SVRI_Assistant", FSVRIAssistant);
|
||||
// 单重:与 Excel 批量匹配逻辑一致(production_order.drawing_no → process_route.material_code);图号用物料编码 partNumber;库中未查到则为 null
|
||||
Double dz = iProductionOrderService.resolveSingleWeightByMaterialCode(bomDetails.getPartNumber());
|
||||
if (dz == null) {
|
||||
if (bomDetails.getDanZhong() != null && bomDetails.getSingleWeghit() != null) {
|
||||
dz = bomDetails.getSingleWeghit();
|
||||
} else if (bomDetails.getDanZhong() != null) {
|
||||
dz = bomDetails.getDanZhong();
|
||||
} else if (bomDetails.getSingleWeghit() != null) {
|
||||
dz = bomDetails.getSingleWeghit();
|
||||
}
|
||||
}
|
||||
if (dz != null) {
|
||||
model.addProperty("F_HBYT_DZ", dz);
|
||||
}
|
||||
writeKingdeeParentDanZhong(model, bomDetails, "父级物料建档");
|
||||
// 创建FMaterialGroup对象,并加入Model
|
||||
JsonObject fMaterialGroup = new JsonObject();
|
||||
fMaterialGroup.addProperty("FNumber", "XM-100");
|
||||
@ -1140,20 +1264,7 @@ public class BomDetailsController extends BaseController {
|
||||
model.add("FMaterialGroup", fMaterialGroup);
|
||||
|
||||
model.addProperty("FIsHandleReserve", true);
|
||||
// 单重:与 Excel 批量匹配逻辑一致(production_order.drawing_no → process_route.material_code);图号用物料编码 partNumber;库中未查到则为 null
|
||||
Double dz = iProductionOrderService.resolveSingleWeightByMaterialCode(bomDetail.getPartNumber());
|
||||
if (dz == null) {
|
||||
if (bomDetail.getDanZhong() != null && bomDetail.getSingleWeghit() != null) {
|
||||
dz = bomDetail.getSingleWeghit();
|
||||
} else if (bomDetail.getDanZhong() != null) {
|
||||
dz = bomDetail.getDanZhong();
|
||||
} else if (bomDetail.getSingleWeghit() != null) {
|
||||
dz = bomDetail.getSingleWeghit();
|
||||
}
|
||||
}
|
||||
if (dz != null) {
|
||||
model.addProperty("F_HBYT_DZ", dz);
|
||||
}
|
||||
writeKingdeeParentDanZhong(model, bomDetail, "FB父级物料建档");
|
||||
// 创建SubHeadEntity对象,并加入Model
|
||||
JsonObject subHeadEntity = new JsonObject();
|
||||
model.add("SubHeadEntity", subHeadEntity);
|
||||
@ -1551,21 +1662,9 @@ public class BomDetailsController extends BaseController {
|
||||
json.add("Model", model);
|
||||
|
||||
model.addProperty("FMATERIALID", 0);
|
||||
// 单重:与 Excel 批量匹配逻辑一致(production_order.drawing_no → process_route.material_code);图号用物料编码 partNumber;库中未查到则为 null
|
||||
Double dz = iProductionOrderService.resolveSingleWeightByMaterialCode(bomDetails1.getPartNumber());
|
||||
if (dz == null) {
|
||||
if (bomDetails1.getDanZhong() != null && bomDetails1.getSingleWeghit() != null) {
|
||||
dz = bomDetails1.getSingleWeghit();
|
||||
} else if (bomDetails1.getDanZhong() != null) {
|
||||
dz = bomDetails1.getDanZhong();
|
||||
} else if (bomDetails1.getSingleWeghit() != null) {
|
||||
dz = bomDetails1.getSingleWeghit();
|
||||
}
|
||||
}
|
||||
if (dz != null) {
|
||||
model.addProperty("F_HBYT_DZ", dz);
|
||||
}
|
||||
model.addProperty("FSpecification", bomDetails1.getRemarks());
|
||||
writeKingdeeChildDanZhong(model, bomDetails1, "子项物料建档");
|
||||
// 规格存材质,与电气建档 loadMaterialToDQ 一致(原先误用 remarks,PLM 下 remarks 常为单位)
|
||||
model.addProperty("FSpecification", bomDetails1.getMaterial());
|
||||
model.addProperty("FNumber", bomDetails1.getPartNumber());
|
||||
model.addProperty("FName", bomDetails1.getName());
|
||||
model.addProperty("F_HBYT_ZYCD", bomDetails1.getStateImportance() != null ? bomDetails1.getStateImportance() : "");
|
||||
@ -1575,7 +1674,7 @@ public class BomDetailsController extends BaseController {
|
||||
FSVRIAssistant.addProperty("FNumber", materialProperties.getMaterialAttributeId());
|
||||
model.add("F_SVRI_Assistant", FSVRIAssistant);
|
||||
} else {
|
||||
// 没写材料为默认为空
|
||||
// 字典未命中时默认「成品」(17)
|
||||
JsonObject FSVRIAssistant = new JsonObject();
|
||||
FSVRIAssistant.addProperty("FNumber", "17");
|
||||
model.add("F_SVRI_Assistant", FSVRIAssistant);
|
||||
@ -1858,6 +1957,7 @@ public class BomDetailsController extends BaseController {
|
||||
model.addProperty("FMATERIALID", 0);
|
||||
model.addProperty("FSpecification", bomDetails1.getMaterial());// 规格 为存入的材质字段
|
||||
model.addProperty("F_HBYT_PP", bomDetails1.getWareHouse());// 品牌 为存入的仓库字段
|
||||
writeKingdeeChildDanZhong(model, bomDetails1, "电气子项物料建档");
|
||||
model.addProperty("FNumber", bomDetails1.getPartNumber());
|
||||
model.addProperty("FName", bomDetails1.getName());
|
||||
MaterialProperties materialProperties = iMaterialPropertiesService.selectByAttribute(bomDetails1.getMaterial());
|
||||
@ -1866,7 +1966,7 @@ public class BomDetailsController extends BaseController {
|
||||
FSVRIAssistant.addProperty("FNumber", materialProperties.getMaterialAttributeId());
|
||||
model.add("F_SVRI_Assistant", FSVRIAssistant);
|
||||
} else {
|
||||
// 没写材料为默认为空
|
||||
// 字典未命中时默认「成品」(17)
|
||||
JsonObject FSVRIAssistant = new JsonObject();
|
||||
FSVRIAssistant.addProperty("FNumber", "17");
|
||||
model.add("F_SVRI_Assistant", FSVRIAssistant);
|
||||
@ -1881,15 +1981,17 @@ public class BomDetailsController extends BaseController {
|
||||
// 创建SubHeadEntity对象,并加入Model
|
||||
JsonObject subHeadEntity = new JsonObject();
|
||||
model.add("SubHeadEntity", subHeadEntity);
|
||||
if (bomDetails1.getWareHouse().contains("伊特")) {
|
||||
subHeadEntity.addProperty("FErpClsID", "2");
|
||||
// 与生产建档一致:按 determineState 结果写物料属性(1外购/2自制/3委外),不再仅凭仓库含「伊特」默认外购
|
||||
String erpClsId = StringUtils.isNotBlank(states) ? states : "1";
|
||||
if (StringUtils.isNotBlank(bomDetails1.getWareHouse()) && bomDetails1.getWareHouse().contains("伊特")) {
|
||||
erpClsId = "2";
|
||||
}
|
||||
subHeadEntity.addProperty("FErpClsID", "1");
|
||||
subHeadEntity.addProperty("FErpClsID", erpClsId);
|
||||
subHeadEntity.addProperty("FFeatureItem", "1");
|
||||
|
||||
// 创建FCategoryID对象,并加入SubHeadEntity
|
||||
JsonObject fCategoryID = new JsonObject();
|
||||
if (states.equals("2") || states.equals("3")) {
|
||||
if (erpClsId.equals("2") || erpClsId.equals("3")) {
|
||||
fCategoryID.addProperty("FNumber", "007");
|
||||
} else {
|
||||
fCategoryID.addProperty("FNumber", "006");
|
||||
@ -2318,14 +2420,15 @@ public class BomDetailsController extends BaseController {
|
||||
bomDetails.setName(bomVO.getDrawingName());
|
||||
bomDetails.setMaterial(bomVO.getModel());
|
||||
bomDetails.setWareHouse(bomVO.getBrand());
|
||||
if(bomVO.getBrand().contains("伊特")){
|
||||
String brand = bomVO.getBrand();
|
||||
if (brand != null && brand.contains("伊特")) {
|
||||
bomDetails.setStats("自制");
|
||||
} else {
|
||||
bomDetails.setStats("外购");
|
||||
}
|
||||
bomDetails.setStats("外购");
|
||||
bomDetails.setQuantity(bomVO.getQuantity() == null ? null : bomVO.getQuantity().toString());
|
||||
bomDetails.setRemarks(bomVO.getUnit());
|
||||
bomDetails.setUpdateTime(new Date());
|
||||
bomDetails.setQuantity(String.valueOf(bomVO.getQuantity()));
|
||||
bomDetails.setDenominator(1.0);
|
||||
bomDetails.setBomType("1");
|
||||
list.add(bomDetails);
|
||||
|
||||
@ -18,6 +18,7 @@ import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.JdUtils;
|
||||
import com.ruoyi.common.utils.KingdeeMaterialCategoryHelper;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.domain.BomDetails;
|
||||
import com.ruoyi.system.domain.BomVariable;
|
||||
@ -425,7 +426,8 @@ public class BomVariableController extends BaseController {
|
||||
}
|
||||
// 创建FCategoryID对象,并加入SubHeadEntity
|
||||
JsonObject fCategoryID = new JsonObject();
|
||||
fCategoryID.addProperty("FNumber", "007");
|
||||
fCategoryID.addProperty("FNumber", KingdeeMaterialCategoryHelper.resolveChildCategoryFNumber(
|
||||
states, partNumber));
|
||||
subHeadEntity.add("FCategoryID", fCategoryID);
|
||||
|
||||
// 创建FTaxRateId对象,并加入SubHeadEntity
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.system.domain.bo.DingSchemeApplicationBo;
|
||||
import com.ruoyi.system.domain.vo.DingSchemeApplicationDetailVo;
|
||||
import com.ruoyi.system.domain.vo.DingSchemeApplicationVo;
|
||||
import com.ruoyi.system.service.IDingSchemeApplicationPlmPushService;
|
||||
import com.ruoyi.system.service.IDingSchemeApplicationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 钉钉技术方案申请归档 — 查询与 PLM 推送管理。
|
||||
*/
|
||||
@Validated
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/system/ding/scheme")
|
||||
public class DingSchemeApplicationController extends BaseController {
|
||||
|
||||
private final IDingSchemeApplicationService dingSchemeApplicationService;
|
||||
private final IDingSchemeApplicationPlmPushService plmPushService;
|
||||
|
||||
/**
|
||||
* 分页查询技术方案申请归档
|
||||
*/
|
||||
@SaCheckPermission("system:dingSchemeApplication:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<DingSchemeApplicationVo> list(DingSchemeApplicationBo bo, PageQuery pageQuery) {
|
||||
return dingSchemeApplicationService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 技术方案申请详情(含 formLabelMap、wfValuesJson)
|
||||
*/
|
||||
@SaCheckPermission("system:dingSchemeApplication:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<DingSchemeApplicationDetailVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
return R.ok(dingSchemeApplicationService.queryDetail(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动推送 PLM
|
||||
*/
|
||||
@SaCheckLogin
|
||||
@PostMapping("/{id}/push-plm")
|
||||
public R<Void> pushPlm(@PathVariable Long id, @RequestParam(defaultValue = "false") boolean force) {
|
||||
try {
|
||||
boolean pushed = plmPushService.pushById(id, force);
|
||||
return pushed ? R.ok() : R.fail("未执行推送(已成功、未启用或记录不存在)");
|
||||
} catch (ServiceException ex) {
|
||||
return R.fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,13 +22,18 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.excel.ExcelResult;
|
||||
import com.ruoyi.common.utils.JdUtils;
|
||||
import com.ruoyi.system.domain.BomDetails;
|
||||
import com.ruoyi.system.domain.EleMaterials;
|
||||
import com.ruoyi.system.domain.ImMaterial;
|
||||
import com.ruoyi.system.domain.MaterialProperties;
|
||||
import com.ruoyi.system.domain.PartCost;
|
||||
import com.ruoyi.system.domain.ProcessRoute;
|
||||
import com.ruoyi.system.domain.dto.*;
|
||||
import com.ruoyi.system.domain.vo.ExcelVo;
|
||||
import com.ruoyi.system.mapper.BomDetailsMapper;
|
||||
import com.ruoyi.system.mapper.ImMaterialMapper;
|
||||
import com.ruoyi.system.mapper.PartCostMapper;
|
||||
import com.ruoyi.system.mapper.ProcessRouteMapper;
|
||||
import com.ruoyi.system.runner.JdUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@ -47,9 +52,11 @@ import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.domain.MaterialProperties;
|
||||
import com.ruoyi.system.domain.vo.EleMaterialsVo;
|
||||
import com.ruoyi.system.domain.bo.EleMaterialsBo;
|
||||
import com.ruoyi.system.service.IEleMaterialsService;
|
||||
import com.ruoyi.system.service.IMaterialPropertiesService;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@ -69,6 +76,9 @@ public class EleMaterialsController extends BaseController {
|
||||
private final ImMaterialMapper materialMapper;
|
||||
private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class);
|
||||
private final PartCostMapper partCostMapper;
|
||||
private final IMaterialPropertiesService iMaterialPropertiesService;
|
||||
private final BomDetailsMapper bomDetailsMapper;
|
||||
private final ProcessRouteMapper processRouteMapper;
|
||||
|
||||
/**
|
||||
* 查询电器物料管理列表
|
||||
@ -557,6 +567,183 @@ public class EleMaterialsController extends BaseController {
|
||||
return R.ok("更新成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 批量更新金蝶物料材质(规格 + 材质辅助资料)。
|
||||
* Excel 只需「物料编码」(物料名称可选);材质从本地库匹配:
|
||||
* bom_details.part_number → material,找不到再查 process_route.material_code → material。
|
||||
*/
|
||||
@Log(title = "更新物料材质", businessType = BusinessType.IMPORT)
|
||||
@SaCheckPermission("system:route:updateDanzhong")
|
||||
@PostMapping(value = "/updateCaizhi", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<String> updateCaizhi(@RequestParam("file") MultipartFile file) throws Exception {
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
log.info("更新材质,读取文件: {}", originalFilename);
|
||||
ExcelResult<JdCaiZhi> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdCaiZhi.class, true);
|
||||
List<JdCaiZhi> list = result.getList();
|
||||
if (list == null || list.isEmpty()) {
|
||||
return R.fail("Excel 无有效数据");
|
||||
}
|
||||
|
||||
List<String> codes = list.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(JdCaiZhi::getMaterialCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(String::trim)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (codes.isEmpty()) {
|
||||
return R.fail("Excel 无有效物料编码");
|
||||
}
|
||||
|
||||
Map<String, String> codeToMaterial = resolveMaterialFromDb(codes);
|
||||
|
||||
long totalRows = 0;
|
||||
long submitted = 0;
|
||||
long skippedBlank = 0;
|
||||
long skippedNoDbMaterial = 0;
|
||||
long skippedNoDict = 0;
|
||||
int failedTasks = 0;
|
||||
List<String> notFoundCodes = Collections.synchronizedList(new ArrayList<>());
|
||||
List<String> noDbMaterials = new ArrayList<>();
|
||||
List<String> noDictMaterials = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||
List<Future<Void>> futures = new ArrayList<>();
|
||||
|
||||
try {
|
||||
for (JdCaiZhi row : list) {
|
||||
totalRows++;
|
||||
if (row == null || StringUtils.isBlank(row.getMaterialCode())) {
|
||||
skippedBlank++;
|
||||
continue;
|
||||
}
|
||||
final String materialCode = row.getMaterialCode().trim();
|
||||
String materialFromDb = codeToMaterial.get(materialCode);
|
||||
if (StringUtils.isBlank(materialFromDb)) {
|
||||
skippedNoDbMaterial++;
|
||||
noDbMaterials.add(materialCode);
|
||||
log.warn("本地库未匹配到材质,跳过: {}", materialCode);
|
||||
continue;
|
||||
}
|
||||
final String materialName = materialFromDb.trim();
|
||||
|
||||
MaterialProperties props = iMaterialPropertiesService.selectByAttribute(materialName);
|
||||
final String attributeId;
|
||||
if (props != null && StringUtils.isNotBlank(props.getMaterialAttributeId())) {
|
||||
attributeId = props.getMaterialAttributeId();
|
||||
} else {
|
||||
attributeId = "17";
|
||||
skippedNoDict++;
|
||||
noDictMaterials.add(materialCode + "(" + materialName + ")");
|
||||
log.warn("材质字典未命中,默认成品17: code={}, material={}", materialCode, materialName);
|
||||
}
|
||||
|
||||
futures.add(executor.submit(() -> {
|
||||
List<JdEntryVmi> entryID = JdUtil.getEntryID2(materialCode);
|
||||
if (entryID == null || entryID.isEmpty()) {
|
||||
notFoundCodes.add(materialCode);
|
||||
log.warn("金蝶未查到物料编码: {}", materialCode);
|
||||
return null;
|
||||
}
|
||||
for (JdEntryVmi jdEntryVmi : entryID) {
|
||||
int fmaterialid = jdEntryVmi.getFMATERIALID();
|
||||
log.info("开始更新材质 code={}, fmaterialid={}, attributeId={}, material={}",
|
||||
materialCode, fmaterialid, attributeId, materialName);
|
||||
JdUtil.updateCaizhi(fmaterialid, attributeId, materialName);
|
||||
}
|
||||
return null;
|
||||
}));
|
||||
submitted++;
|
||||
}
|
||||
|
||||
for (Future<Void> future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (ExecutionException e) {
|
||||
failedTasks++;
|
||||
log.error("更新物料材质任务异常: {}", e.getCause() != null ? e.getCause().getMessage() : e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.error("更新物料材质被中断", e);
|
||||
return R.fail("任务被中断");
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
try {
|
||||
if (!executor.awaitTermination(60, TimeUnit.MINUTES)) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
executor.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
String summary = String.format(
|
||||
"扫描行=%d, 提交=%d, 跳过空编码=%d, 库中无材质=%d, 字典未命中默认17=%d, 金蝶未找到=%d, 失败任务=%d",
|
||||
totalRows, submitted, skippedBlank, skippedNoDbMaterial, skippedNoDict, notFoundCodes.size(), failedTasks);
|
||||
log.info("updateCaizhi 完成: {}, 库中无材质样例={}, 未找到编码样例={}, 未命中字典样例={}",
|
||||
summary,
|
||||
noDbMaterials.stream().limit(20).collect(Collectors.toList()),
|
||||
notFoundCodes.stream().limit(20).collect(Collectors.toList()),
|
||||
noDictMaterials.stream().limit(20).collect(Collectors.toList()));
|
||||
|
||||
if (failedTasks > 0) {
|
||||
return R.fail("部分失败: " + summary);
|
||||
}
|
||||
return R.ok(summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按物料编码从本地库解析材质:优先 bom_details,其次 process_route。
|
||||
*/
|
||||
private Map<String, String> resolveMaterialFromDb(List<String> codes) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (codes == null || codes.isEmpty()) {
|
||||
return map;
|
||||
}
|
||||
final int batchSize = 500;
|
||||
for (int i = 0; i < codes.size(); i += batchSize) {
|
||||
List<String> batch = codes.subList(i, Math.min(i + batchSize, codes.size()));
|
||||
|
||||
List<BomDetails> bomRows = bomDetailsMapper.selectList(
|
||||
Wrappers.<BomDetails>lambdaQuery()
|
||||
.in(BomDetails::getPartNumber, batch)
|
||||
.isNotNull(BomDetails::getMaterial)
|
||||
.ne(BomDetails::getMaterial, "")
|
||||
.select(BomDetails::getPartNumber, BomDetails::getMaterial, BomDetails::getId)
|
||||
.orderByDesc(BomDetails::getId));
|
||||
for (BomDetails row : bomRows) {
|
||||
if (row == null || StringUtils.isBlank(row.getPartNumber()) || StringUtils.isBlank(row.getMaterial())) {
|
||||
continue;
|
||||
}
|
||||
map.putIfAbsent(row.getPartNumber().trim(), row.getMaterial().trim());
|
||||
}
|
||||
|
||||
List<String> missing = batch.stream()
|
||||
.filter(c -> !map.containsKey(c))
|
||||
.collect(Collectors.toList());
|
||||
if (missing.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<ProcessRoute> routeRows = processRouteMapper.selectList(
|
||||
Wrappers.<ProcessRoute>lambdaQuery()
|
||||
.in(ProcessRoute::getMaterialCode, missing)
|
||||
.isNotNull(ProcessRoute::getMaterial)
|
||||
.ne(ProcessRoute::getMaterial, "")
|
||||
.select(ProcessRoute::getMaterialCode, ProcessRoute::getMaterial, ProcessRoute::getId)
|
||||
.orderByDesc(ProcessRoute::getId));
|
||||
for (ProcessRoute row : routeRows) {
|
||||
if (row == null || StringUtils.isBlank(row.getMaterialCode()) || StringUtils.isBlank(row.getMaterial())) {
|
||||
continue;
|
||||
}
|
||||
map.putIfAbsent(row.getMaterialCode().trim(), row.getMaterial().trim());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT)
|
||||
@SaCheckPermission("system:route:updaDateCangwei")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,111 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.vo.KingdeeMaterialDocHubVo;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.system.domain.dto.ProcessReportDTO;
|
||||
import com.ruoyi.system.domain.dto.SubcontractOperationTransferRowDTO;
|
||||
import com.ruoyi.system.domain.vo.MaterialDocHubBoardVo;
|
||||
import com.ruoyi.system.domain.vo.MaterialDocHubDetailVo;
|
||||
import com.ruoyi.system.domain.vo.MaterialDocHubProjectVo;
|
||||
import com.ruoyi.system.service.IKingdeeMaterialDocHubService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 金蝶生产单据整合:按生产令号从总装配 BOM 出发,聚合库存、MO/PO、工序计划、汇报、入库、委外。
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/kingdee/materialDocHub")
|
||||
public class KingdeeMaterialDocHubController {
|
||||
|
||||
private final IKingdeeMaterialDocHubService kingdeeMaterialDocHubService;
|
||||
|
||||
/**
|
||||
* 按生产令号查询整合数据(BOM 主轴)。
|
||||
* <p>示例:{@code GET /system/kingdee/materialDocHub/query?sclh=QB-26-106-LT}</p>
|
||||
*/
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/query")
|
||||
public R<KingdeeMaterialDocHubVo> query(@RequestParam("sclh") String sclh) {
|
||||
if (StringUtils.isBlank(sclh)) {
|
||||
throw new ServiceException("生产令号不能为空");
|
||||
}
|
||||
return R.ok(kingdeeMaterialDocHubService.queryBySclh(sclh.trim()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 工序计划看板分页(默认每页 20,最大 100)。令号可选。
|
||||
*/
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board/page")
|
||||
public TableDataInfo<MaterialDocHubProjectVo> boardPage(
|
||||
@RequestParam(value = "sclh", required = false) String sclh,
|
||||
PageQuery pageQuery) {
|
||||
if (pageQuery.getPageSize() == null) {
|
||||
pageQuery.setPageSize(20);
|
||||
}
|
||||
return kingdeeMaterialDocHubService.queryBoardPage(
|
||||
StringUtils.isNotBlank(sclh) ? sclh.trim() : null, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 展开工单:仅工序计划(按工序号排序)。
|
||||
*/
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board/detail")
|
||||
public R<MaterialDocHubDetailVo> boardDetail(
|
||||
@RequestParam("moBillNo") String moBillNo,
|
||||
@RequestParam("materialNumber") String materialNumber) {
|
||||
return R.ok(kingdeeMaterialDocHubService.queryBoardDetail(moBillNo, materialNumber));
|
||||
}
|
||||
|
||||
/** 按需加载:工序汇报 */
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board/reports")
|
||||
public R<List<ProcessReportDTO>> boardReports(
|
||||
@RequestParam("moBillNo") String moBillNo,
|
||||
@RequestParam(value = "materialNumber", required = false) String materialNumber,
|
||||
@RequestParam(value = "operNumber", required = false) String operNumber) {
|
||||
return R.ok(kingdeeMaterialDocHubService.queryBoardReports(moBillNo, materialNumber, operNumber));
|
||||
}
|
||||
|
||||
/** 按需加载:入库点质检与生产入库 */
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board/instockQc")
|
||||
public R<List<ProcessReportDTO>> boardInstockQc(
|
||||
@RequestParam("moBillNo") String moBillNo,
|
||||
@RequestParam(value = "materialNumber", required = false) String materialNumber,
|
||||
@RequestParam(value = "operNumber", required = false) String operNumber) {
|
||||
return R.ok(kingdeeMaterialDocHubService.queryBoardInstockQc(moBillNo, materialNumber, operNumber));
|
||||
}
|
||||
|
||||
/** 按需加载:委外 C/G */
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board/subcontract")
|
||||
public R<List<SubcontractOperationTransferRowDTO>> boardSubcontract(
|
||||
@RequestParam("moBillNo") String moBillNo) {
|
||||
return R.ok(kingdeeMaterialDocHubService.queryBoardSubcontract(moBillNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 全量查询易超时,请使用 /board/page
|
||||
*/
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/board")
|
||||
public R<MaterialDocHubBoardVo> board(@RequestParam(value = "sclh", required = false) String sclh) {
|
||||
throw new ServiceException("请使用分页接口 /board/page");
|
||||
}
|
||||
}
|
||||
@ -32,4 +32,10 @@ public class KingdeeOrderTraceController {
|
||||
KingdeeOrderTraceVo data = mssqlQueryService.queryOrderTrace(bo);
|
||||
return R.ok(data);
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:mssql:query")
|
||||
@GetMapping("/all")
|
||||
public R<KingdeeOrderTraceVo> all() {
|
||||
return R.ok(mssqlQueryService.queryOrderTraceAll());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,106 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.bo.Nd3CustomKitBo;
|
||||
import com.ruoyi.system.domain.vo.nd3.Nd3PhasedProductProjectVo;
|
||||
import com.ruoyi.system.domain.vo.nd3.Nd3PhasedProductReportVo;
|
||||
import com.ruoyi.system.service.INd3PhasedProductService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 专项 ND3 项目(阶段性产品)报表接口。
|
||||
* <ul>
|
||||
* <li>{@code /search}:按物料号/令号关键字检索</li>
|
||||
* <li>{@code /report}:生产令号、物料编码至少填一项;可直接输入物料号查 BOM 及指标</li>
|
||||
* </ul>
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/system/nd3/phased-product")
|
||||
public class Nd3PhasedProductController {
|
||||
|
||||
private final INd3PhasedProductService nd3PhasedProductService;
|
||||
|
||||
/**
|
||||
* 检索:支持物料编码(金蝶 BOM 父项)或 ND3 生产令号。
|
||||
*/
|
||||
@SaCheckLogin
|
||||
@GetMapping("/search")
|
||||
public R<List<Nd3PhasedProductProjectVo>> search(@RequestParam String keyword) {
|
||||
if (StringUtils.isBlank(keyword)) {
|
||||
return R.fail("请输入物料编码或生产令号");
|
||||
}
|
||||
return R.ok(nd3PhasedProductService.searchProjects(keyword.trim()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 报表:{@code materialCode} 与 {@code productionOrderNo} 至少填一项。
|
||||
* 仅物料号时按金蝶 BOM 展开子项,发货/在途表头为全项目合计,下钻仍按令号汇总。
|
||||
*/
|
||||
@SaCheckLogin
|
||||
@GetMapping("/report")
|
||||
public R<Nd3PhasedProductReportVo> report(
|
||||
@RequestParam(required = false) String productionOrderNo,
|
||||
@RequestParam(required = false) String materialCode,
|
||||
@RequestParam(required = false) Integer inputQty) {
|
||||
if (StringUtils.isBlank(productionOrderNo) && StringUtils.isBlank(materialCode)) {
|
||||
return R.fail("请填写物料编码或生产令号");
|
||||
}
|
||||
return R.ok(nd3PhasedProductService.buildReport(
|
||||
StringUtils.isNotBlank(productionOrderNo) ? productionOrderNo.trim() : null,
|
||||
StringUtils.isNotBlank(materialCode) ? materialCode.trim() : null,
|
||||
inputQty));
|
||||
}
|
||||
|
||||
/**
|
||||
* 多主产品联合齐套试算:各父项分别输入投单量,子项按物料合并并展示各父项单台用量。
|
||||
*/
|
||||
@SaCheckLogin
|
||||
@PostMapping("/custom-kit")
|
||||
public R<Nd3PhasedProductReportVo> customKit(@RequestBody Nd3CustomKitBo bo) {
|
||||
if (bo == null || bo.getParents() == null || bo.getParents().isEmpty()) {
|
||||
return R.fail("请至少填写一个主产品及投单量");
|
||||
}
|
||||
boolean hasValid = bo.getParents().stream()
|
||||
.anyMatch(p -> p != null
|
||||
&& StringUtils.isNotBlank(p.getMaterialCode())
|
||||
&& p.getInputQty() != null
|
||||
&& p.getInputQty() > 0);
|
||||
if (!hasValid) {
|
||||
return R.fail("请填写主产品编码及大于 0 的投单量");
|
||||
}
|
||||
return R.ok(nd3PhasedProductService.buildCustomKitReport(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 多主产品联合齐套试算导出 Excel。
|
||||
*/
|
||||
@SaCheckLogin
|
||||
@PostMapping("/custom-kit/export")
|
||||
public void exportCustomKit(@RequestBody Nd3CustomKitBo bo, HttpServletResponse response) {
|
||||
if (bo == null || bo.getParents() == null || bo.getParents().isEmpty()) {
|
||||
throw new ServiceException("请至少填写一个主产品及投单量");
|
||||
}
|
||||
boolean hasValid = bo.getParents().stream()
|
||||
.anyMatch(p -> p != null
|
||||
&& StringUtils.isNotBlank(p.getMaterialCode())
|
||||
&& p.getInputQty() != null
|
||||
&& p.getInputQty() > 0);
|
||||
if (!hasValid) {
|
||||
throw new ServiceException("请填写主产品编码及大于 0 的投单量");
|
||||
}
|
||||
nd3PhasedProductService.exportCustomKitReport(bo, response);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.ruoyi.system.controller;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@ -108,9 +109,12 @@ public class PartCostController extends BaseController {
|
||||
|
||||
|
||||
/**
|
||||
* 在金蝶获取成本价
|
||||
* 在金蝶获取成本价(支持 XXL-JOB 定时同步)
|
||||
* JobHandler: getObtainPartData
|
||||
*/
|
||||
@SaCheckPermission("system:cost:getObtainPartData")
|
||||
// @SaCheckPermission("system:cost:getObtainPartData")
|
||||
@SaIgnore
|
||||
@XxlJob("getObtainPartData")
|
||||
@Log(title = "在金蝶获取成本价", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/getObtainPartData")
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.system.domain.bo.PlmPdfZipPushBo;
|
||||
import com.ruoyi.system.domain.vo.PlmPdfZipPushDetailVo;
|
||||
import com.ruoyi.system.domain.vo.PlmPdfZipPushVo;
|
||||
import com.ruoyi.system.service.IPlmPdfZipPushService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* PLM PDF 压缩包推送记录
|
||||
*/
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/plmPdfZipPush")
|
||||
public class PlmPdfZipPushController extends BaseController {
|
||||
|
||||
private final IPlmPdfZipPushService plmPdfZipPushService;
|
||||
|
||||
/**
|
||||
* 分页查询推送记录
|
||||
*/
|
||||
@SaCheckPermission("system:plmPdfZipPush:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<PlmPdfZipPushVo> list(PlmPdfZipPushBo bo, PageQuery pageQuery) {
|
||||
return plmPdfZipPushService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载推送明细中的 PLM DWG(校验项目「是否允许下载图纸」)
|
||||
*/
|
||||
@SaCheckPermission("system:plmPdfZipPush:query")
|
||||
@Log(title = "下载PLM DWG图纸", businessType = BusinessType.OTHER)
|
||||
@GetMapping("/downloadDwgItem/{itemId}")
|
||||
public void downloadDwgItem(@NotNull(message = "明细ID不能为空") @PathVariable Long itemId,
|
||||
HttpServletResponse response) {
|
||||
try {
|
||||
File file = plmPdfZipPushService.resolveDownloadableDwgFile(itemId);
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode(file.getName(), "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
|
||||
response.setContentLengthLong(file.length());
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
OutputStream os = response.getOutputStream()) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int length;
|
||||
while ((length = fis.read(buffer)) > 0) {
|
||||
os.write(buffer, 0, length);
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
} catch (ServiceException e) {
|
||||
writeJsonFail(response, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("下载PLM DWG失败 itemId={}", itemId, e);
|
||||
writeJsonFail(response, "下载失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送记录详情(含 manifest JSON 与明细)
|
||||
*/
|
||||
@SaCheckPermission("system:plmPdfZipPush:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<PlmPdfZipPushDetailVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
return R.ok(plmPdfZipPushService.queryDetail(id));
|
||||
}
|
||||
|
||||
private void writeJsonFail(HttpServletResponse response, String msg) {
|
||||
try {
|
||||
if (!response.isCommitted()) {
|
||||
response.reset();
|
||||
}
|
||||
response.setContentType("application/json;charset=utf-8");
|
||||
response.getWriter().write(JSONObject.toJSONString(R.fail(msg)));
|
||||
} catch (IOException ex) {
|
||||
log.error("写入错误响应失败", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
|
||||
import com.ruoyi.system.domain.vo.ProcessOrderProVo;
|
||||
import com.ruoyi.system.domain.vo.plm.PlmProductionOrderVo;
|
||||
import com.ruoyi.system.service.IProcessOrderProService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* PLM 查询生产令号清单。
|
||||
* <p>
|
||||
* GET /system/plm/productionOrders
|
||||
*/
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/plm")
|
||||
public class PlmProductionOrderController extends BaseController {
|
||||
|
||||
private final IProcessOrderProService processOrderProService;
|
||||
|
||||
/**
|
||||
* 分页查询生产令号清单(有哪些生产令号)。
|
||||
* <p>
|
||||
* 可选筛选:productionOrderNo(模糊)、productionName(模糊)、source(手动/PLM)、
|
||||
* bomStatus(项目状态,如 2=工艺待审核、6=开始生产)、routeStatus(工艺审核状态)<br>
|
||||
* 分页:pageNum、pageSize(默认按创建时间倒序)
|
||||
*/
|
||||
@SaIgnore
|
||||
@GetMapping("/productionOrders")
|
||||
public TableDataInfo<PlmProductionOrderVo> productionOrders(ProcessOrderProBo bo, PageQuery pageQuery) {
|
||||
TableDataInfo<ProcessOrderProVo> page = processOrderProService.queryPageList(bo, pageQuery);
|
||||
List<ProcessOrderProVo> rows = page.getRows();
|
||||
List<PlmProductionOrderVo> mapped = rows == null ? Collections.emptyList()
|
||||
: rows.stream().map(this::toPlmVo).collect(Collectors.toList());
|
||||
TableDataInfo<PlmProductionOrderVo> result = new TableDataInfo<>(mapped, page.getTotal());
|
||||
result.setCode(page.getCode());
|
||||
result.setMsg(page.getMsg());
|
||||
return result;
|
||||
}
|
||||
|
||||
private PlmProductionOrderVo toPlmVo(ProcessOrderProVo src) {
|
||||
PlmProductionOrderVo vo = new PlmProductionOrderVo();
|
||||
vo.setId(src.getId());
|
||||
vo.setProductionOrderNo(src.getProductionOrderNo());
|
||||
vo.setProductionName(src.getProductionName());
|
||||
vo.setSource(src.getSource());
|
||||
vo.setQuantity(src.getQuantity());
|
||||
vo.setUnit(src.getUnit());
|
||||
vo.setNeedProcess(src.getNeedProcess());
|
||||
vo.setBomStatus(src.getBomStatus());
|
||||
vo.setBomStatusLabel(resolveBomStatusLabel(src.getBomStatus()));
|
||||
vo.setRouteStatus(src.getRouteStatus());
|
||||
vo.setRouteStatusLabel(resolveRouteStatusLabel(src.getRouteStatus()));
|
||||
vo.setPlanStartTime(src.getPlanStartTime());
|
||||
vo.setPlanEndTime(src.getPlanEndTime());
|
||||
vo.setCreateTime(src.getCreateTime());
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目状态:0方案设计完成 … 2工艺待审核 … 6开始生产 … 8工艺审核完成 … 9工艺审核拒绝
|
||||
*/
|
||||
private static String resolveBomStatusLabel(Long status) {
|
||||
if (status == null) {
|
||||
return null;
|
||||
}
|
||||
switch (status.intValue()) {
|
||||
case 0:
|
||||
return "方案设计完成";
|
||||
case 1:
|
||||
return "设计出图完成";
|
||||
case 2:
|
||||
return "工艺待审核";
|
||||
case 3:
|
||||
return "已推送BOM";
|
||||
case 4:
|
||||
return "已推送工艺";
|
||||
case 5:
|
||||
return "已核算MRP";
|
||||
case 6:
|
||||
return "开始生产";
|
||||
case 7:
|
||||
return "生产完成";
|
||||
case 8:
|
||||
return "工艺审核完成";
|
||||
case 9:
|
||||
return "工艺审核拒绝";
|
||||
default:
|
||||
return String.valueOf(status);
|
||||
}
|
||||
}
|
||||
|
||||
/** 工艺审核:0未审核 1已审核 2已拒绝 */
|
||||
private static String resolveRouteStatusLabel(Long status) {
|
||||
if (status == null) {
|
||||
return null;
|
||||
}
|
||||
switch (status.intValue()) {
|
||||
case 0:
|
||||
return "未审核";
|
||||
case 1:
|
||||
return "已审核";
|
||||
case 2:
|
||||
return "已拒绝";
|
||||
default:
|
||||
return String.valueOf(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.bo.PlmReceiveLogBo;
|
||||
import com.ruoyi.system.domain.vo.PlmReceiveLogVo;
|
||||
import com.ruoyi.system.service.IPlmReceiveLogService;
|
||||
import com.ruoyi.system.service.IProductionOrderService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PLM 总装 BOM / 工艺路线接收留痕
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/plmReceiveLog")
|
||||
public class PlmReceiveLogController extends BaseController {
|
||||
|
||||
private final IPlmReceiveLogService plmReceiveLogService;
|
||||
private final IProductionOrderService productionOrderService;
|
||||
|
||||
@SaCheckPermission("system:plmReceiveLog:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<PlmReceiveLogVo> list(PlmReceiveLogBo bo, PageQuery pageQuery) {
|
||||
return plmReceiveLogService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:plmReceiveLog:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<PlmReceiveLogVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
return R.ok(plmReceiveLogService.queryDetail(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按留痕记录的生产令号,将 production_order 总装行手动同步到 bom_details(bomType=0)。
|
||||
*/
|
||||
@SaCheckPermission("system:plmReceiveLog:syncBomDetails")
|
||||
@Log(title = "PLM接收留痕-同步bom_details", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/{id}/syncBomDetails")
|
||||
public R<Map<String, Object>> syncBomDetails(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
PlmReceiveLogVo logVo = plmReceiveLogService.queryDetail(id);
|
||||
if (logVo == null) {
|
||||
throw new ServiceException("接收记录不存在");
|
||||
}
|
||||
if (StringUtils.isBlank(logVo.getProductionOrderNo())) {
|
||||
throw new ServiceException("该记录无生产令号,无法同步 bom_details");
|
||||
}
|
||||
String orderNo = logVo.getProductionOrderNo().trim();
|
||||
int count = productionOrderService.syncAssemblyBomDetailsByOrderNo(orderNo);
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("productionOrderNo", orderNo);
|
||||
data.put("savedCount", count);
|
||||
data.put("bizType", logVo.getBizType());
|
||||
return R.ok("已同步 " + count + " 条总装行到 bom_details", data);
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,9 @@ import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.ruoyi.common.excel.DefaultExcelListener;
|
||||
import com.ruoyi.common.config.DrawingFtpProperties;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.ruoyi.common.utils.FtpUtil;
|
||||
import com.ruoyi.common.utils.HttpUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
@ -21,7 +23,11 @@ import com.ruoyi.common.utils.VersionComparator;
|
||||
import com.ruoyi.common.utils.file.SmbUtil;
|
||||
import com.ruoyi.common.poi.ExcelTemplateProc;
|
||||
import com.ruoyi.common.poi.DynamicDataMapping;
|
||||
import com.ruoyi.system.constant.ProcessOrderProSource;
|
||||
import com.ruoyi.system.domain.*;
|
||||
import com.ruoyi.system.domain.bo.KingdeeOrderReceiveBatchBo;
|
||||
import com.ruoyi.system.domain.dto.KingdeePrdMoDTO;
|
||||
import com.ruoyi.system.domain.dto.KingdeePurchaseOrderDTO;
|
||||
import com.ruoyi.system.domain.dto.MaterialUseDTO;
|
||||
import com.ruoyi.system.domain.dto.ProcessRouteDTO;
|
||||
import com.ruoyi.system.domain.ProcessRouteExcelDTO1;
|
||||
@ -45,6 +51,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -76,14 +83,23 @@ import shade.com.alibaba.fastjson2.JSONObject;
|
||||
@RequestMapping("/system/orderPro")
|
||||
public class ProcessOrderProController extends BaseController {
|
||||
private final IProcessOrderProService iProcessOrderProService;
|
||||
private final KingdeeOrderReceiveService kingdeeOrderReceiveService;
|
||||
@Autowired
|
||||
private final IMrpResultCheckService iMrpResultCheckService;
|
||||
private final ProcessOrderProMapper processOrderProMapper;
|
||||
private final IImMaterialService imMaterialService;
|
||||
private final ISafetyStockService safetyStockService;
|
||||
private final IProcessRouteService processRouteService;
|
||||
private final IProductionOrderService productionOrderService;
|
||||
private final SafetyStockMapper stockMapper;
|
||||
private final FigureSaveMapper figureSaveMapper;
|
||||
private final DrawingFtpProperties drawingFtpProperties;
|
||||
private final IPlmPdfZipPushService plmPdfZipPushService;
|
||||
private final IDrawingWorkloadService drawingWorkloadService;
|
||||
|
||||
/** 出图 Excel 在 FTP 上的盘符根路径,与 SMB F:\2026\令号 一致 */
|
||||
@Value("${app.drawing.base-path:F:}")
|
||||
private String drawingBasePath;
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
|
||||
@ -111,7 +127,10 @@ public class ProcessOrderProController extends BaseController {
|
||||
@PostMapping("/export")
|
||||
public void export(ProcessOrderProBo bo, HttpServletResponse response) {
|
||||
List<ProcessOrderProVo> list = iProcessOrderProService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "项目令号", ProcessOrderProVo.class, response);
|
||||
List<ProcessOrderProExportVo> exportList = list.stream()
|
||||
.map(ProcessOrderProExportVo::from)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
ExcelUtil.exportExcel(exportList, "项目令号", ProcessOrderProExportVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,7 +268,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
@GetMapping("/getstate")
|
||||
public R<JSONObject> getPlotState() {
|
||||
String result = HttpUtils.sendGet("http://192.168.5.18:9000/getstate", "UTF-8");
|
||||
String result = HttpUtils.sendGet("http://192.168.14.218:9000/getstate", "UTF-8");
|
||||
if (StringUtils.isBlank(result)) {
|
||||
return R.ok("操作成功", null);
|
||||
}
|
||||
@ -293,12 +312,15 @@ public class ProcessOrderProController extends BaseController {
|
||||
|
||||
/**
|
||||
* 下载PDF并生成zip包
|
||||
* <p>业务失败时返回 HTTP 200 + application/json(与 blob 下载约定一致),便于前端解析 msg,
|
||||
* 避免 axios 因 4xx 走错误拦截器只提示「系统接口400异常」。</p>
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:uploadPDF")
|
||||
@Log(title = "下载PDF", businessType = BusinessType.UPDATE)
|
||||
@CrossOrigin(origins = "*", allowedHeaders = "*", exposedHeaders = {"Content-Disposition", "Content-Length"})
|
||||
@GetMapping("/uploadPDF")
|
||||
public void uploadPDF(@RequestParam Long id, HttpServletResponse response) {
|
||||
log.info("下载PDF ZIP 请求: id={}", id);
|
||||
try {
|
||||
// CORS headers for all responses (success and error)
|
||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||
@ -306,9 +328,8 @@ public class ProcessOrderProController extends BaseController {
|
||||
// 调用service方法获取文件路径
|
||||
R<String> result = iProcessOrderProService.uploadPDF(id);
|
||||
if (result.getCode() != 200) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":" + result.getCode() + ",\"msg\":\"" + result.getMsg() + "\"}");
|
||||
log.warn("下载PDF ZIP 生成失败: id={}, code={}, msg={}", id, result.getCode(), result.getMsg());
|
||||
writePdfDownloadJson(response, result);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -317,12 +338,12 @@ public class ProcessOrderProController extends BaseController {
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!file.exists()) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":404,\"msg\":\"文件不存在\"}");
|
||||
log.warn("下载PDF ZIP 文件不存在: id={}, path={}", id, filePath);
|
||||
writePdfDownloadJson(response, R.fail("PDF文件不存在,请稍后重试"));
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("下载PDF ZIP 开始输出: id={}, path={}, size={}", id, filePath, file.length());
|
||||
// 设置响应头
|
||||
response.setContentType("application/zip");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(file.getName(), "UTF-8") + "\"");
|
||||
@ -339,18 +360,35 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
log.info("下载PDF ZIP 输出完成: id={}, file={}", id, file.getName());
|
||||
|
||||
} catch (Exception e) {
|
||||
if (response.isCommitted()) {
|
||||
// 响应已开始写出(多为客户端超时/关闭页面导致连接中断),ZIP 通常已在服务端生成
|
||||
log.warn("客户端已断开连接,PDF/ZIP 可能已在服务端生成: id={}, {}", id, e.getMessage());
|
||||
return;
|
||||
}
|
||||
log.error("下载PDF文件失败", e);
|
||||
try {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
response.getWriter().write("下载失败: " + e.getMessage());
|
||||
writePdfDownloadJson(response, R.fail("PDF下载失败,请稍后重试"));
|
||||
} catch (IOException ex) {
|
||||
log.error("写入错误响应失败", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* blob 下载场景下统一写出 JSON 错误体(HTTP 200 + application/json),msg 安全转义。
|
||||
*/
|
||||
private void writePdfDownloadJson(HttpServletResponse response, R<?> body) throws IOException {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition, Content-Length");
|
||||
response.getWriter().write(JSONObject.toJSONString(body));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载ZIP包
|
||||
*/
|
||||
@ -394,11 +432,17 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (response.isCommitted()) {
|
||||
log.warn("客户端已断开连接,ZIP 可能已在服务端生成: id={}, {}", id, e.getMessage());
|
||||
return;
|
||||
}
|
||||
log.error("下载ZIP包失败", e);
|
||||
try {
|
||||
response.setContentType("text/html;charset=utf-8");
|
||||
response.getWriter().write("下载失败: " + e.getMessage());
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"下载失败\"}");
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
log.error("写入错误响应失败", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,7 +533,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
existingVmi.setQuantity(currentQuantity + itemQuantity);
|
||||
|
||||
Integer currentBatchQuantity = existingVmi.getBatchQuantity() != null ? existingVmi.getBatchQuantity() : 0;
|
||||
Integer itemBatchQuantity = item.getBatchQuantity() != null ? Integer.parseInt(item.getBatchQuantity()) : 0;
|
||||
Integer itemBatchQuantity = parseBatchQuantityAsIntOrZero(item.getBatchQuantity());
|
||||
existingVmi.setBatchQuantity(currentBatchQuantity + itemBatchQuantity);
|
||||
found = true;
|
||||
break;
|
||||
@ -1093,17 +1137,8 @@ public class ProcessOrderProController extends BaseController {
|
||||
map.put("parentDrawingNo", item.getParentDrawingNo());
|
||||
map.put("batchQuantity", item.getBatchQuantity());
|
||||
|
||||
// 为了兼容模板,也提供数字格式的batchQuantity
|
||||
Integer batchQuantityInt = null;
|
||||
if (item.getBatchQuantity() != null && !item.getBatchQuantity().isEmpty()) {
|
||||
try {
|
||||
batchQuantityInt = Integer.valueOf(item.getBatchQuantity());
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果转换失败,保持原值
|
||||
map.put("batchQuantityInt", null);
|
||||
}
|
||||
}
|
||||
map.put("batchQuantityInt", batchQuantityInt);
|
||||
// 为了兼容模板,也提供数字格式的batchQuantity(兼容 "32.0")
|
||||
map.put("batchQuantityInt", parseBatchQuantityAsInt(item.getBatchQuantity()));
|
||||
|
||||
map.put("mainProducts", item.getMainPart());
|
||||
map.put("mainProductsName", item.getMainName());
|
||||
@ -1112,6 +1147,25 @@ public class ProcessOrderProController extends BaseController {
|
||||
return mapList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批次数量转 Integer:兼容 "32" / "32.0"(PLM 常把 Double 存成带小数点的字符串)。
|
||||
*/
|
||||
private static Integer parseBatchQuantityAsInt(String batchQuantity) {
|
||||
if (StringUtils.isBlank(batchQuantity)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (int) Double.parseDouble(batchQuantity.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseBatchQuantityAsIntOrZero(String batchQuantity) {
|
||||
Integer v = parseBatchQuantityAsInt(batchQuantity);
|
||||
return v != null ? v : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换BOM数据为Map列表(用于模板)
|
||||
*/
|
||||
@ -1147,7 +1201,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
vmiData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||
vmiData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||
vmiData.setRemark(item.getRemark());
|
||||
vmiData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||
vmiData.setBatchQuantity(parseBatchQuantityAsInt(item.getBatchQuantity()));
|
||||
return vmiData;
|
||||
}
|
||||
|
||||
@ -1164,7 +1218,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
elecData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||
elecData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||
elecData.setRemark(item.getRemark());
|
||||
elecData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||
elecData.setBatchQuantity(parseBatchQuantityAsInt(item.getBatchQuantity()));
|
||||
return elecData;
|
||||
}
|
||||
|
||||
@ -1181,7 +1235,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
supplierData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||
supplierData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||
supplierData.setRemark(item.getRemark());
|
||||
supplierData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||
supplierData.setBatchQuantity(parseBatchQuantityAsInt(item.getBatchQuantity()));
|
||||
return supplierData;
|
||||
}
|
||||
|
||||
@ -1198,7 +1252,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
evoData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||
evoData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||
evoData.setRemark(item.getRemark());
|
||||
evoData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||
evoData.setBatchQuantity(parseBatchQuantityAsInt(item.getBatchQuantity()));
|
||||
return evoData;
|
||||
}
|
||||
|
||||
@ -1527,7 +1581,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
existingVmi.setQuantity(currentQuantity + itemQuantity);
|
||||
|
||||
Integer currentBatchQuantity = existingVmi.getBatchQuantity() != null ? existingVmi.getBatchQuantity() : 0;
|
||||
Integer itemBatchQuantity = item.getBatchQuantity() != null ? Integer.parseInt(item.getBatchQuantity()) : 0;
|
||||
Integer itemBatchQuantity = parseBatchQuantityAsIntOrZero(item.getBatchQuantity());
|
||||
existingVmi.setBatchQuantity(currentBatchQuantity + itemBatchQuantity);
|
||||
found = true;
|
||||
break;
|
||||
@ -1972,26 +2026,59 @@ public class ProcessOrderProController extends BaseController {
|
||||
|
||||
public String generateRoute3Excel(Long id, boolean isDrawing) throws Exception {
|
||||
ProcessOrderPro orderPro = processOrderProMapper.selectById(id);
|
||||
// 下载Excel文件
|
||||
// 1. 解析年份
|
||||
// PLM 来源:装配 BOM / 工艺表从库读取,不依赖 FTP 汇总表
|
||||
if (ProcessOrderProSource.PLM.equals(orderPro.getSource())) {
|
||||
return generateRoute3ExcelFromPlm(orderPro, isDrawing);
|
||||
}
|
||||
String productionCode = orderPro.getProductionOrderNo();
|
||||
String year = ProductionOrderNoUtils.extractYear(productionCode);
|
||||
|
||||
// 2. 构建FTP路径和本地路径
|
||||
String ftpPath = "/" + year + "/" + productionCode;
|
||||
String localPath = "D:\\file\\";
|
||||
String expectedSummaryName = productionCode + "汇总表.xlsx";
|
||||
String remoteSummaryName = expectedSummaryName;
|
||||
|
||||
// 3. 下载文件 (下载汇总表.xlsx 和 RawDataTable.xlsx)
|
||||
FtpUtil.downloadFtpDirectoryFiles("192.168.5.18", "admin", "hbyt2025", 21, ftpPath, localPath, "汇总表.xlsx");
|
||||
FtpUtil.downloadFtpDirectoryFiles("192.168.5.18", "admin", "hbyt2025", 21, ftpPath, localPath, "RawDataTable.xlsx");
|
||||
String ftpPath = FtpUtil.buildDrawingExcelRemoteDir(drawingBasePath, year, productionCode);
|
||||
log.info("工艺计划表 FTP 下载路径: {} (basePath={})", ftpPath, drawingBasePath);
|
||||
|
||||
// 构建文件路径
|
||||
String excelName = "D:\\file\\" + orderPro.getProductionOrderNo() + "汇总表.xlsx";
|
||||
String rawDataFile = "D:\\file\\" + "RawDataTable.xlsx";
|
||||
R<String> summaryResult = FtpUtil.downloadFtpFile(
|
||||
drawingFtpProperties, ftpPath, localPath, remoteSummaryName, expectedSummaryName);
|
||||
if (R.isError(summaryResult)) {
|
||||
log.warn("汇总表单文件下载失败: {},尝试目录扫描", summaryResult.getMsg());
|
||||
summaryResult = FtpUtil.downloadFtpDirectoryFiles(
|
||||
drawingFtpProperties, ftpPath, localPath, remoteSummaryName);
|
||||
}
|
||||
if (R.isError(summaryResult)) {
|
||||
String fallbackPath = FtpUtil.buildDrawingExcelRemoteDir("", year, productionCode);
|
||||
if (!fallbackPath.equals(ftpPath)) {
|
||||
log.info("尝试无盘符 FTP 路径: {}", fallbackPath);
|
||||
summaryResult = FtpUtil.downloadFtpFile(
|
||||
drawingFtpProperties, fallbackPath, localPath, remoteSummaryName, expectedSummaryName);
|
||||
if (R.isError(summaryResult)) {
|
||||
summaryResult = FtpUtil.downloadFtpDirectoryFiles(
|
||||
drawingFtpProperties, fallbackPath, localPath, remoteSummaryName);
|
||||
}
|
||||
if (R.isSuccess(summaryResult)) {
|
||||
ftpPath = fallbackPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R<String> rawResult = FtpUtil.downloadFtpFile(
|
||||
drawingFtpProperties, ftpPath, localPath, "RawDataTable.xlsx", "RawDataTable.xlsx");
|
||||
if (R.isError(rawResult)) {
|
||||
log.warn("RawDataTable 单文件下载失败: {},尝试目录扫描", rawResult.getMsg());
|
||||
rawResult = FtpUtil.downloadFtpDirectoryFiles(
|
||||
drawingFtpProperties, ftpPath, localPath, "RawDataTable.xlsx");
|
||||
}
|
||||
if (R.isError(rawResult)) {
|
||||
log.warn("RawDataTable 下载: {}", rawResult.getMsg());
|
||||
}
|
||||
|
||||
String excelName = localPath + expectedSummaryName;
|
||||
String rawDataFile = localPath + "RawDataTable.xlsx";
|
||||
File file = new File(excelName);
|
||||
if (!file.exists() || file.length() == 0) {
|
||||
// 如果文件不存在或为空(下载失败),抛出业务异常
|
||||
throw new ServiceException("项目 " + orderPro.getProductionOrderNo() + " 汇总表下载失败或不存在");
|
||||
throw new ServiceException("项目 " + productionCode + " 汇总表下载失败或不存在,FTP路径="
|
||||
+ ftpPath + ",远程文件名=" + remoteSummaryName + "," + summaryResult.getMsg());
|
||||
}
|
||||
// 1. 读取第一个sheet的数据list
|
||||
List<ProductionOrderVo> allDataList = readExcelWithPOI(excelName,orderPro.getProductionOrderNo());
|
||||
@ -2295,15 +2382,7 @@ public class ProcessOrderProController extends BaseController {
|
||||
|
||||
// 合并本批数量 (batchQuantity)
|
||||
Integer currentBatch = existingElec.getBatchQuantity() != null ? existingElec.getBatchQuantity() : 0;
|
||||
Integer itemBatch = 0;
|
||||
try {
|
||||
if (item.getBatchQuantity() != null) {
|
||||
itemBatch = Integer.valueOf(item.getBatchQuantity().toString());
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 转换失败忽略
|
||||
}
|
||||
existingElec.setBatchQuantity(currentBatch + itemBatch);
|
||||
existingElec.setBatchQuantity(currentBatch + parseBatchQuantityAsIntOrZero(item.getBatchQuantity()));
|
||||
|
||||
found = true;
|
||||
break;
|
||||
@ -2408,6 +2487,241 @@ public class ProcessOrderProController extends BaseController {
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* PLM 来源下载工艺计划表:装配 BOM →「总装配材料BOM」;工艺路线 →「工艺及生产计划表」;
|
||||
* 并按规则拆出 VMI/机电件/甲供件/伊特明细。不导出基础 BOM 表;其余明细 sheet 无数据也保留。
|
||||
* 无工艺推送时用装配 BOM 行占位(一物料一行)。不走 FTP。
|
||||
*/
|
||||
private String generateRoute3ExcelFromPlm(ProcessOrderPro orderPro, boolean isDrawing) throws Exception {
|
||||
String productionCode = orderPro.getProductionOrderNo();
|
||||
List<ProductionOrder> orders = productionOrderService.selectByProCode(productionCode);
|
||||
if (orders == null || orders.isEmpty()) {
|
||||
throw new ServiceException("PLM 项目 " + productionCode + " 未找到装配 BOM,请先接收 PLM 推送");
|
||||
}
|
||||
List<ProductionOrderVo> allDataList = BeanUtil.copyToList(orders, ProductionOrderVo.class);
|
||||
|
||||
List<ProcessRoute> routeList = processRouteService.selectByProjectNumber(productionCode);
|
||||
if (routeList == null) {
|
||||
routeList = new ArrayList<>();
|
||||
}
|
||||
if (routeList.isEmpty()) {
|
||||
for (ProductionOrderVo vo : allDataList) {
|
||||
if (vo == null || StringUtils.isBlank(vo.getDrawingNo())) {
|
||||
continue;
|
||||
}
|
||||
ProcessRoute row = new ProcessRoute();
|
||||
row.setRouteDescription(productionCode);
|
||||
row.setMaterialCode(vo.getDrawingNo());
|
||||
row.setMaterialName(vo.getDrawingName());
|
||||
row.setMaterial(vo.getMaterial());
|
||||
row.setDiscWeight(vo.getSingleWeight());
|
||||
row.setUnitQuantity(vo.getQuantity());
|
||||
if (StringUtils.isNotBlank(vo.getBatchQuantity())) {
|
||||
try {
|
||||
row.setBatchQuantity(Long.valueOf(vo.getBatchQuantity().trim()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
routeList.add(row);
|
||||
}
|
||||
}
|
||||
|
||||
// 分类:VMI / 机电件 / 甲供件 / 伊特(不灌基础 BOM)
|
||||
BomClassifyResult classified = classifyAssemblyBomDetails(allDataList);
|
||||
|
||||
String templatePath = "jpg/生产及工艺计划模版.xlsx";
|
||||
String safeOrderNo = sanitizeFileNameSegment(productionCode);
|
||||
String outputPath = isDrawing
|
||||
? ("D:/file/" + safeOrderNo + "工艺表.xlsx")
|
||||
: ("D:/file/" + safeOrderNo + "生产及工艺计划表.xlsx");
|
||||
|
||||
Map<String, Object> staticDataMap = new HashMap<>();
|
||||
staticDataMap.put("productionOrderNo", productionCode);
|
||||
staticDataMap.put("productionName", orderPro.getProductionName());
|
||||
|
||||
List<DynamicDataMapping> dynamicDataMappingList = new ArrayList<>();
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"ProductionOrder", convertProductionOrderToMapList(allDataList, productionCode)));
|
||||
if (!classified.vmiList.isEmpty()) {
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"VMIDataVO", convertVMIDataToMapList(classified.vmiList)));
|
||||
}
|
||||
if (!classified.elecOutList.isEmpty()) {
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"ElecOutDataVO", convertElecOutDataToMapList(classified.elecOutList)));
|
||||
}
|
||||
if (!classified.supplierList.isEmpty()) {
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"SupProvidDataVO", convertSupProvidDataToMapList(classified.supplierList)));
|
||||
}
|
||||
if (!classified.evoProductsList.isEmpty()) {
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"EVOProductsDataVO", convertEVOProductsDataToMapList(classified.evoProductsList)));
|
||||
}
|
||||
// 刻意不添加 BomDataVO —— PLM 不导出基础 BOM 表
|
||||
if (!routeList.isEmpty()) {
|
||||
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList(
|
||||
"RouteBomData", convertRouteBomToMapList(routeList, Collections.emptyList())));
|
||||
}
|
||||
|
||||
log.info("PLM 工艺计划导出 productionCode={} assemblyBom={} routeRows={} vmi={} elec={} supplier={} evo={}",
|
||||
productionCode, allDataList.size(), routeList.size(),
|
||||
classified.vmiList.size(), classified.elecOutList.size(),
|
||||
classified.supplierList.size(), classified.evoProductsList.size());
|
||||
ExcelTemplateProc.doExportExcelByTemplateProc(templatePath, outputPath, staticDataMap, dynamicDataMappingList);
|
||||
|
||||
// PLM 不导出基础 BOM 表;其余明细 sheet 即使无数据也保留
|
||||
removeExcelSheetsByName(outputPath, Collections.singletonList("基础BOM表"));
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
/** 装配 BOM 分类结果(VMI / 机电件 / 甲供件 / 伊特) */
|
||||
private static final class BomClassifyResult {
|
||||
private final List<VMIDataVO> vmiList = new ArrayList<>();
|
||||
private final List<ElecOutDataVO> elecOutList = new ArrayList<>();
|
||||
private final List<SupProvidDataVO> supplierList = new ArrayList<>();
|
||||
private final List<EVOProductsDataVO> evoProductsList = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 总装 BOM 明细分类(与非 PLM 导出一致):
|
||||
* 1) 物料主数据 classificationName=true → VMI
|
||||
* 2) 图号两空格/指定前缀 或 备注|零件类型含「外购」→ 机电件(安全库存除外)
|
||||
* 3) 备注|零件类型含「甲供件」→ 甲供件
|
||||
* 4) 备注|零件类型含「伊特」→ 伊特产品
|
||||
*/
|
||||
private BomClassifyResult classifyAssemblyBomDetails(List<ProductionOrderVo> allDataList) {
|
||||
BomClassifyResult result = new BomClassifyResult();
|
||||
if (allDataList == null || allDataList.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
for (ProductionOrderVo item : allDataList) {
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
String materialCode = item.getDrawingNo();
|
||||
String remark = item.getRemark();
|
||||
String prtType = item.getPrtType();
|
||||
String categoryText = joinCategoryText(remark, prtType);
|
||||
|
||||
if (materialCode == null) {
|
||||
continue;
|
||||
}
|
||||
String drawingNo = item.getDrawingNo();
|
||||
String drawingName = item.getDrawingName();
|
||||
if (drawingName != null) {
|
||||
ImMaterial material = imMaterialService.selectByCodeAndName(drawingNo, drawingName);
|
||||
if (material != null && "true".equals(material.getClassificationName())) {
|
||||
mergeOrAddVmi(result.vmiList, item);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isElecOutMaterialCode(materialCode) || categoryTextContains(categoryText, "外购")) {
|
||||
Boolean isSafeStock = safetyStockService.isSafeCode(materialCode.trim());
|
||||
if (!Boolean.TRUE.equals(isSafeStock)) {
|
||||
mergeOrAddElec(result.elecOutList, item);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (categoryTextContains(categoryText, "甲供件")) {
|
||||
result.supplierList.add(convertToSupProvidDataVO(item));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (categoryTextContains(categoryText, "伊特")) {
|
||||
result.evoProductsList.add(convertToEVOProductsDataVO(item));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String joinCategoryText(String remark, String prtType) {
|
||||
if (StringUtils.isBlank(remark) && StringUtils.isBlank(prtType)) {
|
||||
return "";
|
||||
}
|
||||
if (StringUtils.isBlank(remark)) {
|
||||
return prtType;
|
||||
}
|
||||
if (StringUtils.isBlank(prtType)) {
|
||||
return remark;
|
||||
}
|
||||
return remark + " " + prtType;
|
||||
}
|
||||
|
||||
private static boolean categoryTextContains(String text, String keyword) {
|
||||
return text != null && keyword != null && text.contains(keyword);
|
||||
}
|
||||
|
||||
private static boolean isElecOutMaterialCode(String materialCode) {
|
||||
return materialCode.startsWith(" ")
|
||||
|| materialCode.startsWith("009301") || materialCode.startsWith("009999")
|
||||
|| materialCode.startsWith("017003") || materialCode.startsWith("017002")
|
||||
|| materialCode.startsWith("009001") || materialCode.startsWith("009081");
|
||||
}
|
||||
|
||||
private void mergeOrAddVmi(List<VMIDataVO> vmiList, ProductionOrderVo item) {
|
||||
String drawingNo = item.getDrawingNo();
|
||||
for (VMIDataVO existing : vmiList) {
|
||||
if (drawingNo != null && drawingNo.equals(existing.getDrawingNo())) {
|
||||
Integer currentQuantity = existing.getQuantity() != null ? existing.getQuantity() : 0;
|
||||
Integer itemQuantity = item.getQuantity() != null ? item.getQuantity().intValue() : 0;
|
||||
existing.setQuantity(currentQuantity + itemQuantity);
|
||||
Integer currentBatch = existing.getBatchQuantity() != null ? existing.getBatchQuantity() : 0;
|
||||
existing.setBatchQuantity(currentBatch + parseBatchQuantityAsIntOrZero(item.getBatchQuantity()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
vmiList.add(convertToVMIDataVO(item));
|
||||
}
|
||||
|
||||
private void mergeOrAddElec(List<ElecOutDataVO> elecOutList, ProductionOrderVo item) {
|
||||
for (ElecOutDataVO existing : elecOutList) {
|
||||
if (item.getDrawingNo() != null && item.getDrawingNo().equals(existing.getDrawingNo())) {
|
||||
Double currentQuantity = existing.getQuantity() != null ? existing.getQuantity() : 0.0;
|
||||
Double itemQuantity = item.getQuantity() != null ? item.getQuantity() : 0.0;
|
||||
existing.setQuantity(currentQuantity + itemQuantity);
|
||||
Integer currentBatch = existing.getBatchQuantity() != null ? existing.getBatchQuantity() : 0;
|
||||
existing.setBatchQuantity(currentBatch + parseBatchQuantityAsIntOrZero(item.getBatchQuantity()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
elecOutList.add(convertToElecOutDataVO(item));
|
||||
}
|
||||
|
||||
/** 按名称删除导出 Excel 中的 sheet(从后往前删,避免索引错位) */
|
||||
private void removeExcelSheetsByName(String excelPath, List<String> sheetNames) {
|
||||
if (StringUtils.isBlank(excelPath) || sheetNames == null || sheetNames.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
File file = new File(excelPath);
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
Set<String> toRemove = sheetNames.stream()
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
if (toRemove.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
|
||||
for (int i = workbook.getNumberOfSheets() - 1; i >= 0; i--) {
|
||||
String name = workbook.getSheetName(i);
|
||||
if (toRemove.contains(name)) {
|
||||
workbook.removeSheetAt(i);
|
||||
}
|
||||
}
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
workbook.write(fos);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("删除空 sheet 失败 path={} sheets={} err={}", excelPath, toRemove, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2490,4 +2804,151 @@ public class ProcessOrderProController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载项目 PLM 本地 DWG 图纸(打包 ZIP;校验「是否允许下载项目图纸」)
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:downloadZip")
|
||||
@Log(title = "下载PLM DWG图纸", businessType = BusinessType.OTHER)
|
||||
@GetMapping("/downloadPlmDwg/{id}")
|
||||
public void downloadPlmDwg(@PathVariable("id") Long id, HttpServletResponse response) {
|
||||
try {
|
||||
ProcessOrderProVo orderPro = iProcessOrderProService.queryById(id);
|
||||
if (orderPro == null) {
|
||||
writeJsonFail(response, "项目不存在");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(orderPro.getProductionOrderNo())) {
|
||||
writeJsonFail(response, "项目未配置生产令号");
|
||||
return;
|
||||
}
|
||||
List<File> dwgFiles = plmPdfZipPushService.listDownloadableDwgFiles(orderPro.getProductionOrderNo());
|
||||
String zipName = orderPro.getProductionOrderNo().trim() + "_PLM_DWG.zip";
|
||||
String encoded = URLEncoder.encode(zipName, "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setContentType("application/zip");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encoded);
|
||||
|
||||
try (java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(response.getOutputStream())) {
|
||||
Set<String> usedNames = new HashSet<>();
|
||||
byte[] buffer = new byte[8192];
|
||||
for (File file : dwgFiles) {
|
||||
if (file == null || !file.isFile()) {
|
||||
continue;
|
||||
}
|
||||
String entryName = uniqueZipEntryName(file.getName(), usedNames);
|
||||
zos.putNextEntry(new java.util.zip.ZipEntry(entryName));
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
int len;
|
||||
while ((len = fis.read(buffer)) > 0) {
|
||||
zos.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
zos.closeEntry();
|
||||
}
|
||||
zos.finish();
|
||||
}
|
||||
} catch (ServiceException e) {
|
||||
writeJsonFail(response, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("下载PLM DWG失败 id={}", id, e);
|
||||
writeJsonFail(response, "下载失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String uniqueZipEntryName(String name, Set<String> usedNames) {
|
||||
String base = name == null ? "unnamed.dwg" : name;
|
||||
if (usedNames.add(base)) {
|
||||
return base;
|
||||
}
|
||||
int dot = base.lastIndexOf('.');
|
||||
String prefix = dot > 0 ? base.substring(0, dot) : base;
|
||||
String suffix = dot > 0 ? base.substring(dot) : "";
|
||||
int i = 2;
|
||||
String candidate;
|
||||
do {
|
||||
candidate = prefix + "_" + i + suffix;
|
||||
i++;
|
||||
} while (!usedNames.add(candidate));
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private void writeJsonFail(HttpServletResponse response, String msg) {
|
||||
try {
|
||||
if (!response.isCommitted()) {
|
||||
response.reset();
|
||||
}
|
||||
response.setContentType("application/json;charset=utf-8");
|
||||
response.getWriter().write(JSONObject.toJSONString(R.fail(msg)));
|
||||
} catch (IOException ex) {
|
||||
log.error("写入错误响应失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 FTP 读取「{令号}图纸数量统计表.xlsx」,解析 Sheet1/Sheet2 入库并返回
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:drawingWorkload")
|
||||
@Log(title = "读取图纸工作量", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/drawingWorkload/sync/{id}")
|
||||
public R<DrawingWorkloadVo> syncDrawingWorkload(@NotNull(message = "项目id不能为空") @PathVariable Long id) {
|
||||
return R.ok(drawingWorkloadService.syncFromFtp(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已入库的图纸工作量(含明细)
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:drawingWorkload")
|
||||
@GetMapping("/drawingWorkload/{id}")
|
||||
public R<DrawingWorkloadVo> getDrawingWorkload(@NotNull(message = "项目id不能为空") @PathVariable Long id) {
|
||||
DrawingWorkloadVo vo = drawingWorkloadService.getByOrderProId(id);
|
||||
if (vo == null) {
|
||||
return R.fail("尚未读取图纸工作量,请先点击「读取图纸工作量」");
|
||||
}
|
||||
return R.ok(vo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收金蝶推送的生产/采购订单并入库(支持多个生产令号)
|
||||
*/
|
||||
@SaIgnore
|
||||
@Log(title = "接收金蝶订单", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/kingdee/receive")
|
||||
public R<Void> receiveKingdeeOrders(@Validated @RequestBody KingdeeOrderReceiveBatchBo bo) {
|
||||
kingdeeOrderReceiveService.saveBatch(bo);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按项目 id 查询金蝶生产订单(实时)
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:list")
|
||||
@GetMapping("/kingdee/prdMo/{id}")
|
||||
public R<List<KingdeePrdMoDTO>> getKingdeePrdMo(@NotNull(message = "项目id不能为空") @PathVariable Long id) {
|
||||
String productionOrderNo = resolveProductionOrderNoById(id);
|
||||
List<KingdeePrdMoDTO> list = JdUtil.getKingdeePrdMoByProductionOrderNo(productionOrderNo);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按项目 id 查询金蝶采购订单
|
||||
*/
|
||||
@SaCheckPermission("system:orderPro:list")
|
||||
@GetMapping("/kingdee/purchaseOrder/{id}")
|
||||
public R<List<KingdeePurchaseOrderDTO>> getKingdeePurchaseOrder(@NotNull(message = "项目id不能为空") @PathVariable Long id) {
|
||||
String productionOrderNo = resolveProductionOrderNoById(id);
|
||||
List<KingdeePurchaseOrderDTO> list = JdUtil.getKingdeePurchaseOrderByProductionOrderNo(productionOrderNo);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
private String resolveProductionOrderNoById(Long id) {
|
||||
ProcessOrderProVo orderPro = iProcessOrderProService.queryById(id);
|
||||
if (orderPro == null) {
|
||||
throw new ServiceException("项目不存在");
|
||||
}
|
||||
if (StringUtils.isBlank(orderPro.getProductionOrderNo())) {
|
||||
throw new ServiceException("项目未配置生产令号");
|
||||
}
|
||||
return orderPro.getProductionOrderNo().trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import com.alibaba.excel.support.ExcelTypeEnum;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||
import com.ruoyi.common.config.DrawingFtpProperties;
|
||||
import com.ruoyi.common.config.DingTalkProperties;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
@ -23,6 +24,7 @@ import com.ruoyi.common.excel.ExcelResult;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.FtpUtil;
|
||||
import com.ruoyi.common.utils.KingdeeRouteDepartmentHelper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.SmbUtil;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
@ -84,6 +86,7 @@ public class ProcessRouteController extends BaseController {
|
||||
private final OperationReportWorkshopUpdateService operationReportWorkshopUpdateService;
|
||||
private final IBomDetailsService iBomDetailsService;
|
||||
private final ProcessOrderProMapper proMapper;
|
||||
private final DrawingFtpProperties drawingFtpProperties;
|
||||
private final IImMaterialService materialService;
|
||||
@Autowired
|
||||
BomDetailsMapper bomDetailsMapper;
|
||||
@ -95,6 +98,8 @@ public class ProcessRouteController extends BaseController {
|
||||
private ISysOssService iSysOssService;
|
||||
@Autowired
|
||||
private IProcessOrderProService processOrderProService;
|
||||
/** 计划表落盘 + 按 plan-user-id 推送(与 PLM 导出共用) */
|
||||
private final ProcessPlanExcelPushService processPlanExcelPushService;
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@ -309,7 +314,6 @@ public class ProcessRouteController extends BaseController {
|
||||
}
|
||||
//读取file的所有的物料编码
|
||||
try {
|
||||
|
||||
if (file.exists()) {
|
||||
// 读取Excel的sheet6 从第三行开始 读取到第4列 无数据的跳过
|
||||
DefaultExcelListener<ProcessRoute> listener = new DefaultExcelListener<>(true);
|
||||
@ -418,21 +422,25 @@ public class ProcessRouteController extends BaseController {
|
||||
if (!route.isEmpty()) {
|
||||
return R.fail("项目 " + productionOrderNo + "已导入过工艺 ,请先清空再上传");
|
||||
}
|
||||
String workCenterError = validateImportWorkCenters(list1);
|
||||
if (workCenterError != null) {
|
||||
return R.fail("生产工艺计划表工段校验失败:\n" + workCenterError);
|
||||
}
|
||||
if (iProcessRouteService.saveData(list1, list)) {
|
||||
// 保存临时文件用于发送给指定用户
|
||||
File tempFile = null;
|
||||
// 计划表落到服务器固定目录(app.plan-excel.base-dir/令号/),保留不删
|
||||
File savedPlanFile = null;
|
||||
try {
|
||||
String tempDirPath = "D:/file/";
|
||||
File tempDir = new File(tempDirPath);
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
File dir = new File(processPlanExcelPushService.getPlanExcelBaseDir(), productionOrderNo);
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
log.warn("创建计划表目录失败: {}", dir.getAbsolutePath());
|
||||
}
|
||||
tempFile = new File(tempDirPath + System.currentTimeMillis() + "_" + originalFilename);
|
||||
file.transferTo(tempFile);
|
||||
savedPlanFile = new File(dir, originalFilename);
|
||||
file.transferTo(savedPlanFile);
|
||||
log.info("上传的工艺计划表已落盘: {}", savedPlanFile.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
log.error("保存上传临时文件失败", e);
|
||||
log.error("保存上传的工艺计划表失败", e);
|
||||
}
|
||||
final File uploadFile = tempFile;
|
||||
final File uploadFile = savedPlanFile;
|
||||
|
||||
// 获取当前登录用户昵称(需要在异步线程前获取)
|
||||
String currentUserNickName = "未知用户";
|
||||
@ -448,38 +456,11 @@ public class ProcessRouteController extends BaseController {
|
||||
log.warn("获取当前登录用户昵称失败", e);
|
||||
}
|
||||
|
||||
// 异步发送钉钉卡片和文件
|
||||
// 异步:按 plan-user-id 发文件 + 发工艺审核卡片(落盘文件保留)
|
||||
String finalNickName = currentUserNickName;
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
if (uploadFile != null && uploadFile.exists()) {
|
||||
String planUserIds = dingTalkProperties.getPlanUserId();
|
||||
if (StringUtils.isNotBlank(planUserIds)) {
|
||||
String mediaId = mediaService.uploadMedia("file", uploadFile.getAbsolutePath());
|
||||
// 支持多人推送,假设多个 userId 以逗号分隔
|
||||
String[] userIds = planUserIds.split(",");
|
||||
for (String userId : userIds) {
|
||||
String cleanUserId = userId.trim();
|
||||
if (StringUtils.isNotBlank(cleanUserId)) {
|
||||
try {
|
||||
robotGroupService.sendFileToUser(cleanUserId, mediaId, originalFilename);
|
||||
log.info("上传的工艺计划表已成功发送给用户: {}", cleanUserId);
|
||||
} catch (Exception e) {
|
||||
log.error("发送文件给用户 {} 异常", cleanUserId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.warn("未配置钉钉工艺计划接收人(planUserId),跳过发送文件");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("发送文件给工艺计划接收人异常", e);
|
||||
} finally {
|
||||
if (uploadFile != null && uploadFile.exists()) {
|
||||
uploadFile.delete();
|
||||
}
|
||||
}
|
||||
// 与 PLM 导出推送同一套接收人
|
||||
processPlanExcelPushService.sendToPlanUsers(uploadFile, originalFilename);
|
||||
|
||||
try {
|
||||
ProcessOrderPro order = processOrderProService.selectByProjectNumber(productionOrderNo);
|
||||
@ -497,7 +478,7 @@ public class ProcessRouteController extends BaseController {
|
||||
|
||||
String outTrackId = "audit-card-" + System.currentTimeMillis();
|
||||
// 调用发送给工艺负责人的方法 createAndDeliverCardToUser
|
||||
DingUtil.createAndDeliverCardToUser(
|
||||
DingUtil.createAndDeliverCardToUser(
|
||||
accessToken,
|
||||
dingTalkProperties.getRouteCardTemplateId(),
|
||||
Collections.singletonList(dingTalkProperties.getRouteApprovalId()),
|
||||
@ -571,6 +552,13 @@ public class ProcessRouteController extends BaseController {
|
||||
return iProcessRouteService.pushRouteBom(rooteProdet, groupName);
|
||||
}
|
||||
|
||||
@Log(title = "审核通过(发送钉钉通知,不推送金蝶)")
|
||||
@SaCheckPermission("system:route:approveRoute")
|
||||
@PostMapping("/approveRoute")
|
||||
public R<Void> approveRoute(@RequestParam String rooteProdet) {
|
||||
return processOrderProService.approveRoute(rooteProdet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询项目列表
|
||||
*/
|
||||
@ -656,12 +644,12 @@ public class ProcessRouteController extends BaseController {
|
||||
@SaCheckPermission("system:route:updateProcessPlan")
|
||||
@PostMapping("/updateProcessPlanByWorkshopCustom")
|
||||
public R<List<Model>> updateProcessPlanByWorkshopCustom(
|
||||
@RequestParam String departmentCompare,
|
||||
@RequestParam String departmentNumber,
|
||||
@RequestParam String productCompare,
|
||||
@RequestParam String productFilterValue) throws Exception {
|
||||
@RequestParam String departmentCompare,
|
||||
@RequestParam String departmentNumber,
|
||||
@RequestParam String productCompare,
|
||||
@RequestParam String productFilterValue) throws Exception {
|
||||
return R.ok(operationPlanningWorkshopUpdateService.updateProcessPlanByWorkshopFilter(
|
||||
departmentCompare, departmentNumber, productCompare, productFilterValue));
|
||||
departmentCompare, departmentNumber, productCompare, productFilterValue));
|
||||
}
|
||||
|
||||
@Log(title = "按车间物料更新工序汇报单(默认条件)")
|
||||
@ -676,7 +664,7 @@ public class ProcessRouteController extends BaseController {
|
||||
@PostMapping("/updateOperationReportByWorkshopCustom")
|
||||
public R<List<Model>> updateOperationReportByWorkshopCustom() throws Exception {
|
||||
return R.ok(operationReportWorkshopUpdateService.updateOperationReportByWorkshopFilter(
|
||||
"67", "007", "17", "-MP"));
|
||||
"67", "007", "17", "-MP"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1036,15 +1024,10 @@ public class ProcessRouteController extends BaseController {
|
||||
// 下载Excel模板 (切换为FTP方式)
|
||||
// SmbUtil.downloadExcelFiles(rooteProdet);
|
||||
|
||||
String ftpHost = "192.168.5.18";
|
||||
String ftpUser = "admin";
|
||||
String ftpPass = "hbyt2025";
|
||||
int ftpPort = 21;
|
||||
String localDir = "D:\\file";
|
||||
// 假设远程目录结构与SMB一致,为 /2026/{rooteProdet}
|
||||
String remoteDir = "/2026/" + rooteProdet;
|
||||
|
||||
R<String> ftpResult = FtpUtil.downloadFtpDirectoryFiles(ftpHost, ftpUser, ftpPass, ftpPort, remoteDir, localDir);
|
||||
R<String> ftpResult = FtpUtil.downloadFtpDirectoryFiles(drawingFtpProperties, remoteDir, localDir);
|
||||
if (R.isError(ftpResult)) {
|
||||
log.error("FTP下载失败: {}", ftpResult.getMsg());
|
||||
} else {
|
||||
@ -1109,4 +1092,106 @@ public class ProcessRouteController extends BaseController {
|
||||
List<String> list = iProcessRouteService.updateCgOrders(rooteProdet, cangKuNum);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入前校验「工作中心(加工车间)」:工段合法;
|
||||
* 同一物料下机加(006)与装配(007)可混用,铆焊(018)不得与其他车间混用。
|
||||
*/
|
||||
private static String validateImportWorkCenters(List<ProcessRouteVo> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
validateImportWorkCenterPerRow(list, sb);
|
||||
validateImportMaterialSingleWorkshop(list, sb);
|
||||
return sb.length() == 0 ? null : sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 逐行:工段非空且在允许列表内
|
||||
*/
|
||||
private static void validateImportWorkCenterPerRow(List<ProcessRouteVo> list, StringBuilder sb) {
|
||||
int seq = 0;
|
||||
for (ProcessRouteVo vo : list) {
|
||||
if (vo == null) {
|
||||
continue;
|
||||
}
|
||||
Long processNo = vo.getProcessNo();
|
||||
String workCenter = vo.getWorkCenter();
|
||||
boolean hasProcess = processNo != null;
|
||||
boolean hasWorkCenter = StringUtils.isNotBlank(workCenter);
|
||||
if (!hasProcess && !hasWorkCenter) {
|
||||
continue;
|
||||
}
|
||||
seq++;
|
||||
if (!hasWorkCenter) {
|
||||
appendWorkCenterError(sb, seq, processNo, vo.getMaterialCode(), "工作中心不能为空");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String dept = KingdeeRouteDepartmentHelper.resolveDepartmentFNumber(workCenter);
|
||||
log.debug("工段校验通过 第{}条工艺 processNo={} workCenter={} dept={}",
|
||||
seq, processNo, KingdeeRouteDepartmentHelper.normalize(workCenter), dept);
|
||||
} catch (ServiceException e) {
|
||||
appendWorkCenterError(sb, seq, processNo, vo.getMaterialCode(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一物料编码下:机加(006)与装配(007)允许混用;铆焊(018)不得与机加/装配混用。
|
||||
*/
|
||||
private static void validateImportMaterialSingleWorkshop(List<ProcessRouteVo> list, StringBuilder sb) {
|
||||
Map<String, LinkedHashSet<String>> materialToDepts = new LinkedHashMap<>();
|
||||
Map<String, LinkedHashSet<String>> materialToWorkCenters = new LinkedHashMap<>();
|
||||
for (ProcessRouteVo vo : list) {
|
||||
if (vo == null || vo.getProcessNo() == null || StringUtils.isBlank(vo.getWorkCenter())) {
|
||||
continue;
|
||||
}
|
||||
String materialCode = StringUtils.trim(vo.getMaterialCode());
|
||||
if (StringUtils.isBlank(materialCode)) {
|
||||
continue;
|
||||
}
|
||||
String workCenter = KingdeeRouteDepartmentHelper.normalize(vo.getWorkCenter());
|
||||
String dept;
|
||||
try {
|
||||
dept = KingdeeRouteDepartmentHelper.resolveDepartmentFNumber(workCenter);
|
||||
} catch (ServiceException e) {
|
||||
continue;
|
||||
}
|
||||
materialToDepts.computeIfAbsent(materialCode, k -> new LinkedHashSet<>()).add(dept);
|
||||
materialToWorkCenters.computeIfAbsent(materialCode, k -> new LinkedHashSet<>()).add(workCenter);
|
||||
}
|
||||
for (Map.Entry<String, LinkedHashSet<String>> entry : materialToDepts.entrySet()) {
|
||||
if (!KingdeeRouteDepartmentHelper.hasIncompatibleWorkshops(entry.getValue())) {
|
||||
continue;
|
||||
}
|
||||
String materialCode = entry.getKey();
|
||||
String deptDesc = entry.getValue().stream()
|
||||
.map(d -> KingdeeRouteDepartmentHelper.departmentLabel(d) + "(" + d + ")")
|
||||
.collect(Collectors.joining("、"));
|
||||
String wcDesc = String.join("、", materialToWorkCenters.getOrDefault(materialCode, new LinkedHashSet<>()));
|
||||
if (sb.length() > 0) {
|
||||
sb.append('\n');
|
||||
}
|
||||
sb.append("物料 ").append(materialCode)
|
||||
.append(" 的工艺路线存在不兼容的加工车间(").append(deptDesc)
|
||||
.append("),涉及工段:").append(wcDesc)
|
||||
.append(";机加与装配可同物料混用,铆焊车间不得与其他车间混用");
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendWorkCenterError(StringBuilder sb, int seq, Long processNo, String materialCode, String msg) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append('\n');
|
||||
}
|
||||
sb.append("第").append(seq).append("条工艺");
|
||||
if (processNo != null) {
|
||||
sb.append(" 工序号=").append(processNo);
|
||||
}
|
||||
if (StringUtils.isNotBlank(materialCode)) {
|
||||
sb.append(" 物料=").append(materialCode);
|
||||
}
|
||||
sb.append(":").append(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,165 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.system.domain.ProcessOrderPro;
|
||||
import com.ruoyi.system.domain.bo.plm.PlmProcessRoutePushBo;
|
||||
import com.ruoyi.system.domain.bo.plm.PlmProcessRoutePushNormalizer;
|
||||
import com.ruoyi.system.mapper.ProcessOrderProMapper;
|
||||
import com.ruoyi.system.service.IPlmProcessRoutePushService;
|
||||
import com.ruoyi.system.service.IPlmReceiveLogService;
|
||||
import com.ruoyi.system.service.ProcessPlanExcelPushService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* PLM 系统推送完整工艺信息接收入口(POST JSON,英文键名)。
|
||||
*
|
||||
* @see PlmProcessRoutePushBo
|
||||
*/
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/plm")
|
||||
public class ProcessRoutePushReceiveController extends BaseController {
|
||||
|
||||
private static final String API_PATH = "/system/plm/routReceive";
|
||||
|
||||
private final IPlmProcessRoutePushService plmProcessRoutePushService;
|
||||
private final IPlmReceiveLogService plmReceiveLogService;
|
||||
private final ProcessOrderProMapper processOrderProMapper;
|
||||
/** 导出计划表落盘 + 按 plan-user-id 推送(与手动上传一致) */
|
||||
private final ProcessPlanExcelPushService processPlanExcelPushService;
|
||||
|
||||
/**
|
||||
* 接收一个生产令号下的物料、材料 BOM、工艺路线及工步数据。
|
||||
* <p>
|
||||
* POST /system/plm/routReceive<br>
|
||||
* Content-Type: application/json; charset=UTF-8
|
||||
*/
|
||||
@SaIgnore
|
||||
@Log(title = "PLM工艺信息推送接收", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/routReceive")
|
||||
public R<PlmProcessRoutePushNormalizer.PlmProcessRoutePushSummary> receive(
|
||||
@Validated @RequestBody PlmProcessRoutePushBo body) {
|
||||
String payloadJson = JSON.toJSONString(body);
|
||||
String orderNo = body == null ? null : body.getProductionOrder();
|
||||
String clientIp = resolveClientIp();
|
||||
try {
|
||||
PlmProcessRoutePushNormalizer.normalize(body);
|
||||
PlmProcessRoutePushNormalizer.PlmProcessRoutePushSummary summary = plmProcessRoutePushService.persist(body);
|
||||
log.info("收到 PLM 工艺推送 productionOrder={} materialCount={} processCount={} stepCount={} bomLineCount={} savedBom={} savedRoute={}",
|
||||
summary.getProductionOrder(), summary.getMaterialCount(),
|
||||
summary.getProcessCount(), summary.getStepCount(), summary.getBomLineCount(),
|
||||
summary.getSavedBomCount(), summary.getSavedRouteCount());
|
||||
log.info("PLM 工艺推送完整 JSON:\n{}", JSON.toJSONString(body, SerializerFeature.PrettyFormat));
|
||||
|
||||
Map<String, Object> summaryMap = new LinkedHashMap<>();
|
||||
summaryMap.put("productionOrder", summary.getProductionOrder());
|
||||
summaryMap.put("materialCount", summary.getMaterialCount());
|
||||
summaryMap.put("bomLineCount", summary.getBomLineCount());
|
||||
summaryMap.put("processCount", summary.getProcessCount());
|
||||
summaryMap.put("stepCount", summary.getStepCount());
|
||||
summaryMap.put("savedBomCount", summary.getSavedBomCount());
|
||||
summaryMap.put("savedMaterialBomCount", summary.getSavedMaterialBomCount());
|
||||
summaryMap.put("savedRouteCount", summary.getSavedRouteCount());
|
||||
int saved = summary.getSavedBomCount() + summary.getSavedMaterialBomCount() + summary.getSavedRouteCount();
|
||||
plmReceiveLogService.record(
|
||||
IPlmReceiveLogService.BIZ_PROCESS_ROUTE,
|
||||
API_PATH,
|
||||
summary.getProductionOrder(),
|
||||
payloadJson,
|
||||
JSON.toJSONString(summaryMap),
|
||||
summary.getMaterialCount(),
|
||||
saved,
|
||||
Boolean.TRUE,
|
||||
IPlmReceiveLogService.STATUS_SUCCESS,
|
||||
null,
|
||||
clientIp
|
||||
);
|
||||
|
||||
// 入库成功后异步:导出工艺计划表 → 落盘 → 推送给 plan-user-id(与手动上传同一套用户)
|
||||
final String productionOrder = summary.getProductionOrder();
|
||||
CompletableFuture.runAsync(() -> exportAndPushPlanExcel(productionOrder));
|
||||
|
||||
return R.ok("接收成功", summary);
|
||||
} catch (Exception e) {
|
||||
Integer lineCount = null;
|
||||
if (body != null && body.getMaterialList() != null) {
|
||||
lineCount = body.getMaterialList().size();
|
||||
}
|
||||
plmReceiveLogService.record(
|
||||
IPlmReceiveLogService.BIZ_PROCESS_ROUTE,
|
||||
API_PATH,
|
||||
orderNo,
|
||||
payloadJson,
|
||||
null,
|
||||
lineCount,
|
||||
null,
|
||||
null,
|
||||
IPlmReceiveLogService.STATUS_FAIL,
|
||||
e.getMessage(),
|
||||
clientIp
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PLM 工艺入库后:按模板导出计划表,存到 app.plan-excel.base-dir,再按 plan-user-id 推送。
|
||||
*/
|
||||
private void exportAndPushPlanExcel(String productionOrder) {
|
||||
try {
|
||||
ProcessOrderPro order = processOrderProMapper.selectByProjectNumber(productionOrder);
|
||||
if (order == null || order.getId() == null) {
|
||||
log.warn("PLM 导出计划表跳过:项目不存在 productionOrder={}", productionOrder);
|
||||
return;
|
||||
}
|
||||
// 复用现有导出(PLM 来源会走 generateRoute3ExcelFromPlm)
|
||||
ProcessOrderProController controller = SpringUtils.getBean(ProcessOrderProController.class);
|
||||
String generatedPath = controller.generateRoute3Excel(order.getId(), true);
|
||||
File generated = new File(generatedPath);
|
||||
if (!generated.exists() || generated.length() <= 0) {
|
||||
log.warn("PLM 导出计划表失败:文件为空 path={}", generatedPath);
|
||||
return;
|
||||
}
|
||||
// 落到固定目录,再推送;临时生成文件可删
|
||||
File saved = processPlanExcelPushService.savePlanExcel(productionOrder, generated, generated.getName());
|
||||
File toSend = saved != null ? saved : generated;
|
||||
processPlanExcelPushService.sendToPlanUsers(toSend, toSend.getName());
|
||||
if (saved != null && generated.exists() && !generated.getAbsolutePath().equals(saved.getAbsolutePath())) {
|
||||
if (!generated.delete()) {
|
||||
log.warn("删除临时计划表失败: {}", generated.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("PLM 工艺推送后导出/推送计划表失败 productionOrder={}", productionOrder, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String resolveClientIp() {
|
||||
try {
|
||||
return ServletUtils.getClientIP();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.system.domain.vo.PurchaseOrderApprovalQueryVo;
|
||||
import com.ruoyi.system.runner.JdUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 金蝶采购订单查询
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/purchaseOrder")
|
||||
public class PurchaseOrderController extends BaseController {
|
||||
|
||||
/**
|
||||
* 采购订单审批状态分类:审批中(B)、重新审批(D)。
|
||||
*
|
||||
* @param productionOrderNo 生产令号,可选,模糊匹配 F_UCHN_Text2
|
||||
* @param materialCode 物料编码,可选,精确匹配
|
||||
*/
|
||||
@SaCheckPermission("system:workCenterData:list")
|
||||
@GetMapping("/approval")
|
||||
public R<PurchaseOrderApprovalQueryVo> approvalQuery(
|
||||
@RequestParam(required = false) String productionOrderNo,
|
||||
@RequestParam(required = false) String materialCode) {
|
||||
try {
|
||||
return R.ok(JdUtil.getPurchaseOrderApprovalGrouped(productionOrderNo, materialCode));
|
||||
} catch (Exception e) {
|
||||
return R.fail("查询采购订单审批数据失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.system.domain.dto.ratio.RatioBuildCapacityDTO;
|
||||
import com.ruoyi.system.service.IRatioBuildCapacityService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/ratio")
|
||||
public class RatioBuildCapacityController {
|
||||
|
||||
private final IRatioBuildCapacityService ratioBuildCapacityService;
|
||||
|
||||
@GetMapping("/buildCapacity")
|
||||
public R<RatioBuildCapacityDTO> buildCapacity(@RequestParam("ratioValue") BigDecimal ratioValue,
|
||||
@RequestParam("qty") Integer qty) {
|
||||
return R.ok(ratioBuildCapacityService.queryByRatio(ratioValue, qty));
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,6 @@ import com.ruoyi.system.domain.bo.SfcOperationPlanningMainBo;
|
||||
import com.ruoyi.system.service.ISfcOperationPlanningMainService;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
|
||||
import com.ruoyi.system.domain.dto.OperationPlanResultDTO;
|
||||
import com.ruoyi.system.domain.dto.OperationPlanningUpdateOperatorsReq;
|
||||
|
||||
@ -71,6 +69,27 @@ public class SfcOperationPlanningMainController extends BaseController {
|
||||
return iSfcOperationPlanningMainService.queryCascadePageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出工序进度(按生产令号分 Sheet,过滤已完工/已关闭)
|
||||
*/
|
||||
@SaCheckPermission("system:operationPlanningMain:export")
|
||||
@Log(title = "工序计划进度导出", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportCascadeProgress")
|
||||
public void exportCascadeProgress(SfcOperationPlanningMainBo bo, HttpServletResponse response) {
|
||||
iSfcOperationPlanningMainService.exportCascadeProgress(bo, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目进度推送:生成进度 Excel,用「信息发送」机器人私发给配置人员。
|
||||
* <p>接收人见 dingtalk.info-send-user-ids;机器人 ding9bhxctsmq5jsf8pk。
|
||||
*/
|
||||
@SaCheckPermission("system:operationPlanningMain:export")
|
||||
@Log(title = "项目进度推送", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/pushCascadeProgress")
|
||||
public R<String> pushCascadeProgress(SfcOperationPlanningMainBo bo) {
|
||||
return iSfcOperationPlanningMainService.pushCascadeProgress(bo);
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:operationPlanningMain:updateOperators")
|
||||
@Log(title = "工序作业人员/设备更新", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateOperators")
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.core.validate.AddGroup;
|
||||
import com.ruoyi.common.core.validate.EditGroup;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.domain.bo.WorkAlertPushConfigBo;
|
||||
import com.ruoyi.system.domain.vo.WorkAlertPushConfigVo;
|
||||
import com.ruoyi.system.service.IWorkAlertPushConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 预警钉钉定时推送配置
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/workAlertPushConfig")
|
||||
public class WorkAlertPushConfigController extends BaseController {
|
||||
|
||||
private final IWorkAlertPushConfigService workAlertPushConfigService;
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<WorkAlertPushConfigVo> list(WorkAlertPushConfigBo bo, PageQuery pageQuery) {
|
||||
return workAlertPushConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:export")
|
||||
@Log(title = "预警推送配置", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(WorkAlertPushConfigBo bo, HttpServletResponse response) {
|
||||
List<WorkAlertPushConfigVo> list = workAlertPushConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "预警推送配置", WorkAlertPushConfigVo.class, response);
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<WorkAlertPushConfigVo> getInfo(@NotNull @PathVariable Long id) {
|
||||
return R.ok(workAlertPushConfigService.queryById(id));
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:list")
|
||||
@GetMapping("/pushTypes")
|
||||
public R<List<Map<String, String>>> pushTypes() {
|
||||
return R.ok(workAlertPushConfigService.listPushTypeOptions());
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:add")
|
||||
@Log(title = "预警推送配置", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody WorkAlertPushConfigBo bo) {
|
||||
return toAjax(workAlertPushConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:edit")
|
||||
@Log(title = "预警推送配置", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WorkAlertPushConfigBo bo) {
|
||||
return toAjax(workAlertPushConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:remove")
|
||||
@Log(title = "预警推送配置", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty @PathVariable Long[] ids) {
|
||||
return toAjax(workAlertPushConfigService.deleteWithValidByIds(Arrays.asList(ids), true));
|
||||
}
|
||||
|
||||
@SaCheckPermission("system:workAlertPushConfig:trigger")
|
||||
@Log(title = "预警推送配置", businessType = BusinessType.OTHER)
|
||||
@PostMapping("/trigger/{id}")
|
||||
public R<Void> trigger(@NotNull @PathVariable Long id) {
|
||||
workAlertPushConfigService.triggerPush(id);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ public class BomDetails extends BaseEntity {
|
||||
/**
|
||||
* 子项单重
|
||||
*/
|
||||
private Double singleWeghit;
|
||||
private Double singleWeghit;
|
||||
/**
|
||||
*bom类型
|
||||
*/
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 项目图纸工作量汇总(Sheet1)
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("drawing_workload")
|
||||
public class DrawingWorkload extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 项目令号ID */
|
||||
private Long orderProId;
|
||||
|
||||
/** 生产令号 */
|
||||
private String productionOrderNo;
|
||||
|
||||
private Integer a4Count;
|
||||
private Integer a3Count;
|
||||
private Integer a3HalfCount;
|
||||
private Integer a3Plus1Count;
|
||||
private Integer a2Count;
|
||||
private Integer a2HalfCount;
|
||||
private Integer a1Count;
|
||||
private Integer a1HalfCount;
|
||||
private Integer a0Count;
|
||||
private Integer a0HalfCount;
|
||||
|
||||
/** 等效A4图纸总数量 */
|
||||
private Integer equivalentA4Total;
|
||||
|
||||
/** 明细行数 */
|
||||
private Integer itemCount;
|
||||
|
||||
/** 最近同步时间 */
|
||||
private Date syncTime;
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 项目图纸工作量明细(Sheet2)
|
||||
*/
|
||||
@Data
|
||||
@TableName("drawing_workload_item")
|
||||
public class DrawingWorkloadItem {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 汇总ID */
|
||||
private Long workloadId;
|
||||
|
||||
/** 图号 */
|
||||
private String drawingNo;
|
||||
|
||||
/** 名称 */
|
||||
private String drawingName;
|
||||
|
||||
/** 图框名称 */
|
||||
private String frameName;
|
||||
|
||||
/** 图纸幅面 */
|
||||
private String paperSize;
|
||||
|
||||
/** 等效A4图纸数量 */
|
||||
private Integer equivalentA4;
|
||||
|
||||
/** 行序 */
|
||||
private Integer sortNo;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("kingdee_prd_mo")
|
||||
public class KingdeePrdMo {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String productionOrderNo;
|
||||
private String billNo;
|
||||
private String routingNumber;
|
||||
private String workshopName;
|
||||
private String materialCode;
|
||||
private String materialName;
|
||||
private BigDecimal qty;
|
||||
private String materialProperty;
|
||||
private String unitName;
|
||||
private String planStartDate;
|
||||
private String planFinishDate;
|
||||
private String pickMtrlStatus;
|
||||
private Date receiveTime;
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("kingdee_purchase_order")
|
||||
public class KingdeePurchaseOrder {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String productionOrderNo;
|
||||
private String billNo;
|
||||
private String materialCode;
|
||||
private String materialName;
|
||||
private BigDecimal qty;
|
||||
private String orderDate;
|
||||
private String deliveryDate;
|
||||
private BigDecimal remainStockInQty;
|
||||
private String mrpCloseStatus;
|
||||
private String supplierName;
|
||||
private Date receiveTime;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("plm_pdf_zip_push")
|
||||
public class PlmPdfZipPush {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String productionOrderNo;
|
||||
private String archiveName;
|
||||
private String manifestJson;
|
||||
private String savedDir;
|
||||
private Integer itemCount;
|
||||
private Date receiveTime;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("plm_pdf_zip_push_item")
|
||||
public class PlmPdfZipPushItem {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long pushId;
|
||||
private String pdfPath;
|
||||
/** 压缩包内/原始 DWG 路径 */
|
||||
private String dwgPath;
|
||||
private String materialCode;
|
||||
private String materialName;
|
||||
/** 单台数量 */
|
||||
private java.math.BigDecimal unitQty;
|
||||
/** 本批数量 */
|
||||
private java.math.BigDecimal batchQty;
|
||||
/** 是否变更图纸(PLM: IsDrawingChanaged) */
|
||||
private Boolean isDrawingChanged;
|
||||
private String savedFileName;
|
||||
private String savedPath;
|
||||
/** DWG 落盘文件名 */
|
||||
private String savedDwgFileName;
|
||||
/** DWG 落盘完整路径 */
|
||||
private String savedDwgPath;
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* PLM 总装配 BOM / 工艺路线推送接收留痕。
|
||||
*/
|
||||
@Data
|
||||
@TableName("plm_receive_log")
|
||||
public class PlmReceiveLog {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** ASSEMBLY_BOM / PROCESS_ROUTE */
|
||||
private String bizType;
|
||||
|
||||
private String apiPath;
|
||||
|
||||
private String productionOrderNo;
|
||||
|
||||
/** 完整请求 JSON */
|
||||
private String payloadJson;
|
||||
|
||||
private String payloadSha256;
|
||||
|
||||
private Integer payloadSize;
|
||||
|
||||
private String summaryJson;
|
||||
|
||||
private Integer lineCount;
|
||||
|
||||
private Integer savedCount;
|
||||
|
||||
private Boolean replaced;
|
||||
|
||||
/** SUCCESS / FAIL */
|
||||
private String status;
|
||||
|
||||
private String errorMsg;
|
||||
|
||||
private String clientIp;
|
||||
|
||||
private Date receiveTime;
|
||||
}
|
||||
@ -37,6 +37,10 @@ public class ProcessOrderPro extends BaseEntity {
|
||||
* 是否可以下载
|
||||
*/
|
||||
private Integer isDownload;
|
||||
/**
|
||||
* 是否做工艺:0否 1是
|
||||
*/
|
||||
private Integer needProcess;
|
||||
/**
|
||||
* 延期天数
|
||||
*/
|
||||
@ -85,7 +89,7 @@ public class ProcessOrderPro extends BaseEntity {
|
||||
private String drawingPath;
|
||||
|
||||
/**
|
||||
* 项目状态(0方案设计完成,1设计出图完成,2,工艺待审核 3 已推送BOM,4已推送工艺,5已核算MRP, 6开始生产,7生产完成,8 工艺审核完成 )
|
||||
* 项目状态(0方案设计完成,1设计出图完成,2工艺待审核,3已推送BOM,4已推送工艺,5已核算MRP,6开始生产,7生产完成,8工艺审核完成,9工艺审核拒绝)
|
||||
*/
|
||||
private Long bomStatus;
|
||||
/**
|
||||
@ -142,4 +146,19 @@ public class ProcessOrderPro extends BaseEntity {
|
||||
*/
|
||||
private Integer routePlanSendCount;
|
||||
|
||||
/**
|
||||
* 来源:{@link com.ruoyi.system.constant.ProcessOrderProSource#MANUAL} / {@link com.ruoyi.system.constant.ProcessOrderProSource#PLM}
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 金蝶生产订单状态:0待建 1已建(金蝶推送接收后置1)
|
||||
*/
|
||||
private Integer needKingdeePrdMo;
|
||||
|
||||
/**
|
||||
* 金蝶采购订单状态:0待建 1已建(金蝶推送接收后置1)
|
||||
*/
|
||||
private Integer needKingdeePurchaseOrder;
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.ruoyi.common.convert.NullableDoubleConverter;
|
||||
import com.ruoyi.common.convert.NullableLongConverter;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@ -16,7 +18,7 @@ public class ProcessRouteExcelDTO1 {
|
||||
@ExcelProperty(index = 2)
|
||||
private String material;
|
||||
|
||||
@ExcelProperty(index = 3)
|
||||
@ExcelProperty(index = 3, converter = NullableDoubleConverter.class)
|
||||
private Double discWeight;
|
||||
|
||||
@ExcelProperty(index = 4)
|
||||
@ -28,7 +30,7 @@ public class ProcessRouteExcelDTO1 {
|
||||
@ExcelProperty(index = 6)
|
||||
private String bomMaterial;
|
||||
|
||||
@ExcelProperty(index = 7)
|
||||
@ExcelProperty(index = 7, converter = NullableDoubleConverter.class)
|
||||
private Double bomDanZhong;
|
||||
|
||||
@ExcelProperty(index = 8)
|
||||
@ -37,7 +39,7 @@ public class ProcessRouteExcelDTO1 {
|
||||
@ExcelProperty(index = 9)
|
||||
private String bomUnit;
|
||||
|
||||
@ExcelProperty(index = 10)
|
||||
@ExcelProperty(index = 10, converter = NullableLongConverter.class)
|
||||
private Long processNo;
|
||||
|
||||
@ExcelProperty(index = 11)
|
||||
@ -52,16 +54,16 @@ public class ProcessRouteExcelDTO1 {
|
||||
@ExcelProperty(index = 14)
|
||||
private String processControl;
|
||||
|
||||
@ExcelProperty(index = 15)
|
||||
@ExcelProperty(index = 15, converter = NullableDoubleConverter.class)
|
||||
private Double activityDuration;
|
||||
|
||||
@ExcelProperty(index = 16)
|
||||
private String activityUnit;
|
||||
|
||||
@ExcelProperty(index = 17)
|
||||
@ExcelProperty(index = 17, converter = NullableDoubleConverter.class)
|
||||
private Double unitQuantity;
|
||||
|
||||
@ExcelProperty(index = 18)
|
||||
@ExcelProperty(index = 18, converter = NullableLongConverter.class)
|
||||
private Long batchQuantity;
|
||||
|
||||
@ExcelProperty(index = 19)
|
||||
|
||||
@ -1,81 +1,86 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/**
|
||||
* 生产订单对象 production_order
|
||||
*
|
||||
* @author 田志阳
|
||||
* @date 2024-10-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("production_order")
|
||||
public class ProductionOrder extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
/**
|
||||
* 生产令号
|
||||
*/
|
||||
private String productionOrderNo;
|
||||
/**
|
||||
* 生产图号
|
||||
*/
|
||||
private String drawingNo;
|
||||
/**
|
||||
* 生产名称
|
||||
*/
|
||||
private String drawingName;
|
||||
/**
|
||||
* 生产数量
|
||||
*/
|
||||
private Double quantity;
|
||||
/**
|
||||
* 生产材料
|
||||
*/
|
||||
private String material;
|
||||
/**
|
||||
* 单重(kg)
|
||||
*/
|
||||
private Double singleWeight;
|
||||
/**
|
||||
* 总重(kg)
|
||||
*/
|
||||
private Double totalWeight;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 部件名称
|
||||
*/
|
||||
private String parentPart;
|
||||
/**
|
||||
* 部件图号
|
||||
*/
|
||||
private String parentDrawingNo;
|
||||
/**
|
||||
* 主产品名称
|
||||
*/
|
||||
private String mainName;
|
||||
/**
|
||||
* 主产品图号
|
||||
*/
|
||||
private String mainPart;
|
||||
/**
|
||||
* 批次数量
|
||||
*/
|
||||
private String batchQuantity;
|
||||
}
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/**
|
||||
* 生产订单对象 production_order
|
||||
*
|
||||
* @author 田志阳
|
||||
* @date 2024-10-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("production_order")
|
||||
public class ProductionOrder extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
/**
|
||||
* 生产令号
|
||||
*/
|
||||
private String productionOrderNo;
|
||||
/**
|
||||
* 生产图号
|
||||
*/
|
||||
private String drawingNo;
|
||||
/**
|
||||
* 生产名称
|
||||
*/
|
||||
private String drawingName;
|
||||
/**
|
||||
* 单台数量
|
||||
*/
|
||||
private Double quantity;
|
||||
/**
|
||||
* 生产材料
|
||||
*/
|
||||
private String material;
|
||||
/**
|
||||
* 单重(kg)
|
||||
*/
|
||||
private Double singleWeight;
|
||||
/**
|
||||
* 总重(kg)
|
||||
*/
|
||||
private Double totalWeight;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 部件名称
|
||||
*/
|
||||
private String parentPart;
|
||||
/**
|
||||
* 部件图号
|
||||
*/
|
||||
private String parentDrawingNo;
|
||||
/**
|
||||
* 主产品名称
|
||||
*/
|
||||
private String mainName;
|
||||
/**
|
||||
* 主产品图号
|
||||
*/
|
||||
private String mainPart;
|
||||
/**
|
||||
* 批次数量
|
||||
*/
|
||||
private String batchQuantity;
|
||||
|
||||
/**
|
||||
* 零件类型(标准件/自制件/外购件等)
|
||||
*/
|
||||
private String prtType;
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("ratio_accessory")
|
||||
public class RatioAccessory extends BaseEntity {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long ratioConfigId;
|
||||
|
||||
private String materialCode;
|
||||
|
||||
private String materialName;
|
||||
|
||||
private String danzhong;
|
||||
|
||||
private String canzhi;
|
||||
|
||||
private String partCategory;
|
||||
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("ratio_config")
|
||||
public class RatioConfig extends BaseEntity {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private BigDecimal ratioValue;
|
||||
|
||||
private BigDecimal maxTorqueNm;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String remark;
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 预警钉钉定时推送配置 work_alert_push_config
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("work_alert_push_config")
|
||||
public class WorkAlertPushConfig extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 推送任务编码 */
|
||||
private String pushCode;
|
||||
|
||||
/** 推送名称 */
|
||||
private String pushName;
|
||||
|
||||
/** 每日推送时间 HH:mm */
|
||||
private String pushTime;
|
||||
|
||||
/** 钉钉用户 StaffId,逗号分隔 */
|
||||
private String dingUserIds;
|
||||
|
||||
/** 分对象接收人 JSON,如 {"机一工段":"staffId1,staffId2"} */
|
||||
private String recipientRules;
|
||||
|
||||
/** 群会话 ID */
|
||||
private String openConversationId;
|
||||
|
||||
/** 机器人 Code */
|
||||
private String robotCode;
|
||||
|
||||
/** 是否启用 0否 1是 */
|
||||
private String enabled;
|
||||
|
||||
/** 上次推送日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date lastPushDate;
|
||||
|
||||
/** 排序 */
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.ruoyi.system.domain.bo;
|
||||
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 钉钉技术方案申请归档查询条件
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DingSchemeApplicationBo extends BaseEntity {
|
||||
|
||||
private Long id;
|
||||
private String schemeApplyNo;
|
||||
private String overviewName;
|
||||
private String fillerName;
|
||||
private String customerFullName;
|
||||
private String productName;
|
||||
private String plmPushStatus;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.ruoyi.system.domain.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 金蝶批量推送:多个生产令号下的生产/采购订单
|
||||
*/
|
||||
@Data
|
||||
public class KingdeeOrderReceiveBatchBo {
|
||||
|
||||
@NotEmpty(message = "订单列表不能为空")
|
||||
@Valid
|
||||
private List<KingdeeOrderReceiveBo> items;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.ruoyi.system.domain.bo;
|
||||
|
||||
import com.ruoyi.system.domain.dto.KingdeePrdMoDTO;
|
||||
import com.ruoyi.system.domain.dto.KingdeePurchaseOrderDTO;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 金蝶推送:一个生产令号下的生产订单 + 采购订单
|
||||
*/
|
||||
@Data
|
||||
public class KingdeeOrderReceiveBo {
|
||||
|
||||
@NotBlank(message = "生产令号不能为空")
|
||||
private String productionOrderNo;
|
||||
|
||||
private List<KingdeePrdMoDTO> prdMoList;
|
||||
|
||||
private List<KingdeePurchaseOrderDTO> purchaseOrderList;
|
||||
}
|
||||
@ -129,4 +129,19 @@ public class KingdeeWorkCenterDataBo extends BaseEntity {
|
||||
*/
|
||||
private BigDecimal FScrapQty;
|
||||
|
||||
/** 上一序工序号(工艺路线) */
|
||||
private String prevOperNumber;
|
||||
|
||||
/** 上一序工序名称 */
|
||||
private String prevProcessName;
|
||||
|
||||
/** 上一序工作中心 */
|
||||
private String prevWorkCenter;
|
||||
|
||||
/** 查路线使用的物料编码(-MP 物料为去后缀后编码) */
|
||||
private String prevRouteMaterialCode;
|
||||
|
||||
/** 上一序状态:未质检 / 质检未入库 / 上一序未转出 等 */
|
||||
private String prevOperStatus;
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user