package jnpf.dmsIntegration.audit; import jnpf.audit.AuditConsts; import jnpf.audit.diff.AuditFieldDiff; import jnpf.audit.model.AuditEventDTO; import jnpf.audit.sdk.AuditClient; import jnpf.util.JsonUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.beans.factory.ObjectProvider; import org.springframework.web.context.request.RequestContextHolder; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; /** DMS 后端直接变更的审计;不再次记录原生表单的创建/编辑。 */ @Component @RequiredArgsConstructor public class DmsBusinessChangeAudit { private final ObjectProvider clients; private final DmsSystemAudit systemAudit; /** 调用方在实际写入成功后提交旧/新事实;SDK 在事务提交后投递,回滚不投递。 */ public void record(String tenantId, String action, String label, String table, String id, Map before, Map after, String reason, Map context) { String differences = AuditFieldDiff.diff(before, after, Collections.emptySet()); if ("[]".equals(differences)) return; AuditEventDTO event = AuditEventDTO.builder() .tenantId(tenantId).eventType(AuditConsts.TYPE_DATA_CHANGE) .actionCode(action).actionLabel(label).bizModule("DMS").bizType("DMS_BUSINESS_CHANGE") .bizCode(id).targetTable(table).targetId(id).recordTitle(label + " · " + id) .fieldDiffs(differences).dataSnapshot(JsonUtil.getObjectToString(after)) .reason(reason).extra(JsonUtil.getObjectToString(context)) .relatedSigns(DmsAuditRequestSignResolver.resolve(context)).sourceLayer(3).build(); if (RequestContextHolder.getRequestAttributes() == null) { // 自动执行者与批准来源分开;批准人等来源身份由调用方放在 context。 event.setOperatorId("0"); event.setOperatorName("系统自动执行"); systemAudit.record(event); } else { clients.ifAvailable(client -> client.record(event)); } } /** 允许空值,保持旧/新事实中未设置的字段;调用方只选取本次业务变化字段。 */ public static Map values(Object... pairs) { if (pairs.length % 2 != 0) throw new IllegalArgumentException("审计字段必须成对"); Map result = new LinkedHashMap<>(); for (int i = 0; i < pairs.length; i += 2) result.put((String) pairs[i], pairs[i + 1]); return result; } }