From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsService/DmsFileRevisionService.java | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 180 insertions(+), 0 deletions(-)
diff --git a/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsService/DmsFileRevisionService.java b/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsService/DmsFileRevisionService.java
new file mode 100644
index 0000000..44a7c3f
--- /dev/null
+++ b/jnpf-dms/jnpf-dms-biz/src/main/java/jnpf/dmsService/DmsFileRevisionService.java
@@ -0,0 +1,180 @@
+package jnpf.dmsService;
+
+import jnpf.base.UserInfo;
+import jnpf.dmsEntity.permission.entity.DmsDocumentEntity;
+import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
+import jnpf.dmsEntity.permission.entity.DmsPermissionResourceEntity;
+import jnpf.dmsEntity.permission.enums.DmsPermissionAction;
+import jnpf.dmsEntity.permission.enums.DmsResourceType;
+import jnpf.dmsEntity.storage.entity.DmsFileObjectEntity;
+import jnpf.dmsEntity.storage.form.DmsFileRevisionRegisterForm;
+import jnpf.dmsEntity.storage.vo.DmsFileUploadVO;
+import jnpf.dmsIntegration.audit.DmsAuditAdapter;
+import jnpf.dmsMapper.DmsDocumentMapper;
+import jnpf.dmsMapper.DmsFileObjectMapper;
+import jnpf.dmsMapper.DmsFileVersionMapper;
+import jnpf.dmsMapper.DmsPermissionResourceMapper;
+import jnpf.dmsMapper.DmsVersionStateMapper;
+import jnpf.dmsPermission.DmsCurrentIdentity;
+import jnpf.dmsPermission.DmsPermissionError;
+import jnpf.dmsPermission.DmsPermissionException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Locale;
+import java.util.Objects;
+
+@Service
+@RequiredArgsConstructor
+public class DmsFileRevisionService {
+ private static final String SOURCE_PREFIX = "revision:";
+
+ private final DmsCurrentIdentity currentIdentity;
+ private final DmsPermissionDecisionService decisionService;
+ private final DmsDocumentMapper documentMapper;
+ private final DmsFileVersionMapper fileVersionMapper;
+ private final DmsPermissionResourceMapper resourceMapper;
+ private final DmsFileObjectMapper fileObjectMapper;
+ private final DmsVersionStateMapper versionStateMapper;
+ private final DmsAuditAdapter auditAdapter;
+
+ @Transactional
+ public DmsFileUploadVO register(DmsFileRevisionRegisterForm form, String serviceId) {
+ UserInfo user = currentIdentity.requireUser();
+ String tenantId = currentIdentity.tenantId(user);
+ String sourceId = form.getSourceId().trim();
+ decisionService.requireAllowed(DmsResourceType.DOCUMENT, form.getDocumentId(),
+ DmsPermissionAction.UPDATE);
+
+ fileObjectMapper.lockSource(tenantId, serviceId, sourceId);
+ DmsFileUploadVO existing = fileObjectMapper.selectUploadBySource(tenantId, serviceId, sourceId);
+ if (existing != null) {
+ validateRetry(existing, form);
+ return existing;
+ }
+
+ DmsDocumentEntity document = documentMapper.selectByTenantAndIdForUpdate(tenantId,
+ form.getDocumentId());
+ if (document == null) {
+ throw DmsPermissionException.of(DmsPermissionError.RESOURCE_NOT_FOUND, "寰呬慨璁㈡枃浠朵笉瀛樺湪");
+ }
+ DmsFileVersionEntity current = fileVersionMapper.selectCurrentEffective(tenantId,
+ form.getDocumentId());
+ if (current == null || !Objects.equals(current.getId(), form.getBaseFileVersionId())) {
+ throw DmsPermissionException.of(DmsPermissionError.REVISION_CONFLICT,
+ "寰呬慨璁㈢増鏈凡涓嶆槸鐜拌鏈夋晥鐗堟湰锛岃鍒锋柊鍚庨噸璇�");
+ }
+
+ long nextVersionNo = fileVersionMapper.selectNextVersionNo(tenantId, form.getDocumentId());
+ try {
+ insertFileVersion(form, tenantId, user.getUserId(), nextVersionNo);
+ insertRegistry(form, tenantId, serviceId, sourceId);
+ insertFileObject(form, tenantId, user.getUserId(), serviceId, sourceId);
+ int superseded = versionStateMapper.supersedeCurrent(tenantId, form.getDocumentId(),
+ form.getBaseFileVersionId(), form.getVersionLabel().trim(), user.getUserId());
+ if (superseded != 1) {
+ throw DmsPermissionException.of(DmsPermissionError.REVISION_CONFLICT,
+ "鐜拌鏈夋晥鐗堟湰宸插彂鐢熷彉鍖栵紝璇峰埛鏂板悗閲嶈瘯");
+ }
+ versionStateMapper.insertRevisionEffective(tenantId, form.getDocumentId(),
+ form.getBaseFileVersionId(), form.getFileVersionId(), sourceId,
+ form.getRevisionReason().trim(), user.getUserId());
+ } catch (DuplicateKeyException exception) {
+ throw conflict("淇鐧昏鐨勮祫婧� ID銆乻ource_id銆佺増鏈彿銆佺増鏈爣绛炬垨瀵硅薄閿凡琚崰鐢�", exception);
+ }
+
+ auditAdapter.dataChange("UPDATE", "妯℃嫙淇 DMS 鏂囦欢", "dms_documents",
+ form.getDocumentId().toString(),
+ "{\"fileVersionId\":\"" + form.getBaseFileVersionId() + "\"}",
+ "{\"fileVersionId\":\"" + form.getFileVersionId() + "\",\"versionLabel\":\""
+ + escapeJson(form.getVersionLabel().trim()) + "\"}");
+ return fileObjectMapper.selectUploadBySource(tenantId, serviceId, sourceId);
+ }
+
+ private void insertFileVersion(DmsFileRevisionRegisterForm form, String tenantId,
+ String userId, long versionNo) {
+ DmsFileVersionEntity version = new DmsFileVersionEntity();
+ version.setId(form.getFileVersionId());
+ version.setTenantId(tenantId);
+ version.setDocumentId(form.getDocumentId());
+ version.setVersionNo(versionNo);
+ version.setVersionLabel(form.getVersionLabel().trim());
+ version.setFileName(form.getFileName().trim());
+ version.setMimeType(trimToNull(form.getMimeType()));
+ version.setSizeBytes(form.getSizeBytes());
+ version.setChecksumSha256(form.getChecksumSha256().toLowerCase(Locale.ROOT));
+ version.setPreparedBy(form.getPreparedBy().trim());
+ version.setPreparedOn(form.getPreparedOn());
+ version.setCreatedBy(userId);
+ fileVersionMapper.insert(version);
+ }
+
+ private void insertRegistry(DmsFileRevisionRegisterForm form, String tenantId,
+ String serviceId, String sourceId) {
+ DmsPermissionResourceEntity registry = new DmsPermissionResourceEntity();
+ registry.setId(form.getFileVersionId());
+ registry.setTenantId(tenantId);
+ registry.setResourceType(DmsResourceType.FILE_VERSION.name());
+ registry.setSourceType("SYSTEM");
+ registry.setSourceId(SOURCE_PREFIX + sourceId + ":version");
+ registry.setRegisteredBy(serviceId);
+ resourceMapper.insert(registry);
+ }
+
+ private void insertFileObject(DmsFileRevisionRegisterForm form, String tenantId, String userId,
+ String serviceId, String sourceId) {
+ DmsFileObjectEntity object = new DmsFileObjectEntity();
+ object.setId(form.getFileObjectId());
+ object.setTenantId(tenantId);
+ object.setFileVersionId(form.getFileVersionId());
+ object.setStoragePlatform(form.getStoragePlatform().trim());
+ object.setBucketName(form.getBucketName().trim());
+ object.setBasePath(trimToEmpty(form.getBasePath()));
+ object.setObjectPath(form.getObjectPath().trim());
+ object.setObjectName(form.getObjectName().trim());
+ object.setSourceServiceId(serviceId);
+ object.setSourceId(sourceId);
+ object.setCreatedBy(userId);
+ fileObjectMapper.insert(object);
+ }
+
+ private void validateRetry(DmsFileUploadVO existing, DmsFileRevisionRegisterForm form) {
+ if (!Objects.equals(existing.getDocumentId(), form.getDocumentId())
+ || !Objects.equals(existing.getBaseFileVersionId(), form.getBaseFileVersionId())
+ || !Objects.equals(existing.getVersionLabel(), form.getVersionLabel().trim())
+ || !Objects.equals(existing.getFileName(), form.getFileName().trim())
+ || !Objects.equals(existing.getMimeType(), trimToNull(form.getMimeType()))
+ || !Objects.equals(existing.getSizeBytes(), form.getSizeBytes())
+ || !equalsIgnoreCase(existing.getChecksumSha256(), form.getChecksumSha256())
+ || !Objects.equals(existing.getPreparedBy(), form.getPreparedBy().trim())
+ || !Objects.equals(existing.getPreparedOn(), form.getPreparedOn())
+ || !Objects.equals(existing.getRevisionReason(), form.getRevisionReason().trim())) {
+ throw DmsPermissionException.of(DmsPermissionError.IDEMPOTENCY_CONFLICT,
+ "source_id 瀵瑰簲鐨勪慨璁㈠唴瀹逛笌鏈璇锋眰涓嶄竴鑷�");
+ }
+ }
+
+ private String trimToNull(String value) {
+ return value == null || value.trim().isEmpty() ? null : value.trim();
+ }
+
+ private String trimToEmpty(String value) {
+ return value == null ? "" : value.trim();
+ }
+
+ private boolean equalsIgnoreCase(String left, String right) {
+ return left == null ? right == null : right != null && left.equalsIgnoreCase(right);
+ }
+
+ private String escapeJson(String value) {
+ return value.replace("\\", "\\\\").replace("\"", "\\\"");
+ }
+
+ private DmsPermissionException conflict(String message, Throwable cause) {
+ DmsPermissionException exception = DmsPermissionException.of(DmsPermissionError.SOURCE_CONFLICT, message);
+ exception.initCause(cause);
+ return exception;
+ }
+}
--
Gitblit v1.8.0