🐛 修复MK公开页审批回写,并支持OA部门按公司oaId轮询同步
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+20
-4
@@ -1,6 +1,7 @@
|
||||
package org.springblade.transport.mk;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.tenant.annotation.TenantIgnore;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.transport.pojo.dto.BillPaymentStatusRequest;
|
||||
@@ -270,6 +271,7 @@ public final class MkProcessBizHandlers {
|
||||
}
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@TenantIgnore
|
||||
@RequiredArgsConstructor
|
||||
@@ -290,6 +292,12 @@ public final class MkProcessBizHandlers {
|
||||
public boolean syncFromProcessInfo(Long id, Object processInfo) {
|
||||
FormalSettlement entity = service.getById(id);
|
||||
if (entity == null) {
|
||||
log.warn("MK同步当前节点失败,正式结算单不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
// 已终态单据禁止再写回审批中,避免流程结束后的节点刷新把状态打回 reviewing
|
||||
if ("approved".equals(entity.getApprovalStatus()) || "returned".equals(entity.getApprovalStatus())
|
||||
|| "voided".equals(entity.getApprovalStatus())) {
|
||||
return false;
|
||||
}
|
||||
String node = MkProcessNodeHelper.currentNode(processInfo);
|
||||
@@ -310,8 +318,12 @@ public final class MkProcessBizHandlers {
|
||||
@Override
|
||||
public boolean approveFromProcess(Long id, String processorName) {
|
||||
FormalSettlement entity = service.getById(id);
|
||||
if (entity == null || "approved".equals(entity.getApprovalStatus())) {
|
||||
return entity != null;
|
||||
if (entity == null) {
|
||||
log.error("MK审批通过同步失败,正式结算单不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
if ("approved".equals(entity.getApprovalStatus())) {
|
||||
return true;
|
||||
}
|
||||
// 统一走 service.approve:与手动审批同一入口(补变更记录),审批事务提交后自动触发金蝶推送事件;
|
||||
// 仅审批中单据允许通过,重复回调被状态校验拒绝,不重复推送
|
||||
@@ -330,8 +342,12 @@ public final class MkProcessBizHandlers {
|
||||
@Override
|
||||
public boolean rejectFromProcess(Long id, String processorName) {
|
||||
FormalSettlement entity = service.getById(id);
|
||||
if (entity == null || "returned".equals(entity.getApprovalStatus())) {
|
||||
return entity != null;
|
||||
if (entity == null) {
|
||||
log.error("MK审批驳回同步失败,正式结算单不存在 id={}", id);
|
||||
return false;
|
||||
}
|
||||
if ("returned".equals(entity.getApprovalStatus())) {
|
||||
return true;
|
||||
}
|
||||
entity.setApprovalStatus("returned");
|
||||
entity.setCurrentNode("审核不通过");
|
||||
|
||||
+75
-28
@@ -4,10 +4,12 @@ import com.alibaba.fastjson2.JSON;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.tenant.TenantUtil;
|
||||
import org.springblade.core.tenant.annotation.TenantIgnore;
|
||||
import org.springblade.core.tool.api.FR;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.process.feign.IBusinessProcessClient;
|
||||
import org.springblade.process.pojo.vo.MkFormBindVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -69,9 +71,9 @@ public class MkProcessMessageService {
|
||||
log.warn("公开页流程消息未找到 processId,跳过查询当前节点 bizType={}", bizType);
|
||||
return;
|
||||
}
|
||||
String bizIdText = firstText(asMap(body == null ? null : body.get("formData")), "id", "formInstanceId");
|
||||
Long bizId = resolveBizId(asMap(body == null ? null : body.get("formData")));
|
||||
queryCurrentNodes(bizType, processId, loginName);
|
||||
scheduleProcessInfo(handler, bizType, processId, loginName, bizIdText, formValues);
|
||||
scheduleProcessInfo(handler, bizType, processId, loginName, bizId, formValues);
|
||||
}
|
||||
|
||||
private void queryCurrentNodes(String bizType, String processId, String loginName) {
|
||||
@@ -86,36 +88,35 @@ public class MkProcessMessageService {
|
||||
}
|
||||
|
||||
private void scheduleProcessInfo(IMkProcessBizHandler handler, String bizType, String processId,
|
||||
String loginName, String bizIdText, Map<String, Object> formValues) {
|
||||
String loginName, Long bizId, Map<String, Object> formValues) {
|
||||
Map<String, Object> formValuesCopy = new HashMap<>(formValues == null ? Map.of() : formValues);
|
||||
log.info("公开页将在{}秒后查询流程实例详情 bizType={} processId={}", PROCESS_INFO_DELAY_SECONDS, bizType, processId);
|
||||
log.info("公开页将在{}秒后查询流程实例详情 bizType={} processId={} bizId={}",
|
||||
PROCESS_INFO_DELAY_SECONDS, bizType, processId, bizId);
|
||||
// 延迟任务跑在独立线程,请求态 @TenantIgnore 已丢失,必须显式 ignore,否则 getById 可能因租户条件查空
|
||||
scheduler.schedule(
|
||||
() -> queryProcessInfo(handler, bizType, processId, loginName, bizIdText, formValuesCopy),
|
||||
() -> TenantUtil.ignore(() -> queryProcessInfo(handler, bizType, processId, loginName, bizId, formValuesCopy)),
|
||||
PROCESS_INFO_DELAY_SECONDS,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
}
|
||||
|
||||
private void queryProcessInfo(IMkProcessBizHandler handler, String bizType, String processId,
|
||||
String loginName, String bizIdText, Map<String, Object> formValues) {
|
||||
String loginName, Long bizId, Map<String, Object> formValues) {
|
||||
try {
|
||||
FR<Object> processInfoResult = businessProcessClient.getProcessInfo(processId, loginName);
|
||||
Object processInfo = processInfoResult == null ? null : processInfoResult.getData();
|
||||
log.info("公开页流程消息流程实例详情 bizType={} processId={} loginName={} result={}",
|
||||
bizType, processId, loginName, JSON.toJSONString(processInfo));
|
||||
log.info("公开页流程消息流程实例详情 bizType={} processId={} loginName={} bizId={} result={}",
|
||||
bizType, processId, loginName, bizId, JSON.toJSONString(processInfo));
|
||||
if (isProcessFinished(processInfo)) {
|
||||
applyProcessResult(handler, bizType, bizIdText, processId, formValues, true);
|
||||
applyProcessResult(handler, bizType, bizId, processId, formValues, true);
|
||||
} else if (MkProcessNodeHelper.isProcessRejected(processInfo)) {
|
||||
applyProcessResult(handler, bizType, bizIdText, processId, formValues, false);
|
||||
} else if (StringUtil.isNotBlank(bizIdText)) {
|
||||
try {
|
||||
handler.syncFromProcessInfo(Long.valueOf(bizIdText), processInfo);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("公开页流程消息业务id格式不正确 bizType={} id={}", bizType, bizIdText);
|
||||
}
|
||||
applyProcessResult(handler, bizType, bizId, processId, formValues, false);
|
||||
} else if (bizId != null) {
|
||||
handler.syncFromProcessInfo(bizId, processInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("公开页查询流程实例详情失败 bizType={} processId={} loginName={}", bizType, processId, loginName, e);
|
||||
log.error("公开页查询流程实例详情失败 bizType={} processId={} loginName={} bizId={}",
|
||||
bizType, processId, loginName, bizId, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,21 +124,24 @@ public class MkProcessMessageService {
|
||||
return "30".equals(firstText(asMap(processInfo), "fdProcessStatus"));
|
||||
}
|
||||
|
||||
private void applyProcessResult(IMkProcessBizHandler handler, String bizType, String bizIdText,
|
||||
private void applyProcessResult(IMkProcessBizHandler handler, String bizType, Long bizId,
|
||||
String processId, Map<String, Object> formValues, boolean approved) {
|
||||
String action = approved ? "审核通过" : "审核驳回";
|
||||
if (StringUtil.isBlank(bizIdText)) {
|
||||
log.warn("流程{}但未找到业务id,跳过同步 bizType={} processId={}", action, bizType, processId);
|
||||
if (bizId == null) {
|
||||
log.warn("流程{}但未解析到业务主键,跳过同步 bizType={} processId={}", action, bizType, processId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String processorName = firstText(formValues, "mkUserName", "mkLoginName");
|
||||
Long bizId = Long.valueOf(bizIdText);
|
||||
if (approved) {
|
||||
handler.approveFromProcess(bizId, processorName);
|
||||
} else {
|
||||
handler.rejectFromProcess(bizId, processorName);
|
||||
boolean synced = approved
|
||||
? handler.approveFromProcess(bizId, processorName)
|
||||
: handler.rejectFromProcess(bizId, processorName);
|
||||
if (!synced) {
|
||||
log.error("流程{}同步业务状态失败(业务单据不存在或未更新) bizType={} bizId={} processId={}",
|
||||
action, bizType, bizId, processId);
|
||||
return;
|
||||
}
|
||||
log.info("流程{}同步业务状态成功 bizType={} bizId={} processId={}", action, bizType, bizId, processId);
|
||||
try {
|
||||
FR<Boolean> markResult = businessProcessClient.markProcessFinished(processId, approved);
|
||||
log.info("公开页标记业务流程完结 bizType={} processId={} approved={} result={}",
|
||||
@@ -146,13 +150,56 @@ public class MkProcessMessageService {
|
||||
log.error("公开页标记业务流程完结失败 bizType={} processId={} approved={}",
|
||||
bizType, processId, approved, markException);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("流程{}但业务id格式不正确 bizType={} id={}", action, bizType, bizIdText);
|
||||
} catch (Exception e) {
|
||||
log.error("流程{}同步业务状态失败 bizType={} id={} processId={}", action, bizType, bizIdText, processId, e);
|
||||
log.error("流程{}同步业务状态失败 bizType={} bizId={} processId={}", action, bizType, bizId, processId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 公开页 formData 里的 id / formInstanceId 可能是表单实例 id(与业务主键不同),
|
||||
* 须先按 MkFormBind 反查业务主键,与 detail 接口保持一致。
|
||||
*/
|
||||
private Long resolveBizId(Map<String, Object> formData) {
|
||||
String formInstanceIdText = firstText(formData, "formInstanceId");
|
||||
String idText = firstText(formData, "id");
|
||||
Long resolved = resolveByFormInstanceId(formInstanceIdText);
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
resolved = resolveByFormInstanceId(idText);
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
if (StringUtil.isNotBlank(idText)) {
|
||||
try {
|
||||
return Long.valueOf(idText);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("公开页流程消息业务id格式不正确 id={}", idText);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Long resolveByFormInstanceId(String formInstanceIdText) {
|
||||
if (StringUtil.isBlank(formInstanceIdText)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Long formInstanceId = Long.valueOf(formInstanceIdText);
|
||||
FR<MkFormBindVO> result = businessProcessClient.resolveByFormInstanceId(formInstanceId);
|
||||
if (result != null && result.isSuccess() && result.getData() != null && result.getData().getBizId() != null) {
|
||||
Long bizId = result.getData().getBizId();
|
||||
log.info("公开页按表单实例id解析业务主键 formInstanceId={} bizId={}", formInstanceId, bizId);
|
||||
return bizId;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("公开页表单实例id格式不正确 formInstanceId={}", formInstanceIdText);
|
||||
} catch (Exception e) {
|
||||
log.warn("公开页按表单实例id解析业务主键失败 formInstanceId={}", formInstanceIdText, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Map<String, Object> asMap(Object value) {
|
||||
if (!(value instanceof Map<?, ?> map)) {
|
||||
return Collections.emptyMap();
|
||||
|
||||
Reference in New Issue
Block a user