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-file/jnpf-file-storage/src/main/java/jnpf/fileStorage/dms/DmsFileStorageService.java | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 299 insertions(+), 0 deletions(-)
diff --git a/jnpf-file/jnpf-file-storage/src/main/java/jnpf/fileStorage/dms/DmsFileStorageService.java b/jnpf-file/jnpf-file-storage/src/main/java/jnpf/fileStorage/dms/DmsFileStorageService.java
new file mode 100644
index 0000000..46e067a
--- /dev/null
+++ b/jnpf-file/jnpf-file-storage/src/main/java/jnpf/fileStorage/dms/DmsFileStorageService.java
@@ -0,0 +1,299 @@
+package jnpf.fileStorage.dms;
+
+import jnpf.base.ActionResult;
+import jnpf.base.ActionResultCode;
+import jnpf.config.ConfigValueUtil;
+import jnpf.constant.MsgCode;
+import jnpf.dms.DmsResourceApi;
+import jnpf.dmsEntity.storage.form.DmsFileRevisionRegisterForm;
+import jnpf.dmsEntity.storage.form.DmsFileUploadRegisterForm;
+import jnpf.dmsEntity.storage.vo.DmsFileUploadVO;
+import jnpf.exception.DataException;
+import jnpf.util.OptimizeUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UpUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.dromara.x.file.storage.core.FileStorageService;
+import org.dromara.x.file.storage.core.hash.HashInfo;
+import org.dromara.x.file.storage.core.platform.MinioFileStorage;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+import java.util.UUID;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class DmsFileStorageService {
+ static final String STORAGE_PLATFORM = "seaweedfs-1";
+ static final String SERVICE_ID = "jnpf-file";
+
+ private final FileStorageService fileStorageService;
+ private final DmsResourceApi dmsResourceApi;
+ private final ConfigValueUtil configValueUtil;
+
+ public DmsFileUploadVO upload(UUID folderId, String sourceId, String documentNo,
+ String documentName, String documentType,
+ String responsibleDeptId, String versionLabel,
+ String preparedBy, LocalDate preparedOn, MultipartFile file) {
+ validate(sourceId, documentNo, documentName, documentType, responsibleDeptId,
+ versionLabel, preparedBy, preparedOn, file);
+ String originalFilename = safeFilename(file.getOriginalFilename());
+ String extension = UpUtil.getFileType(file);
+ if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), extension)) {
+ throw new DataException(MsgCode.FA017.get());
+ }
+
+ UUID documentId = UuidV7Generator.generate();
+ UUID fileVersionId = UuidV7Generator.generate();
+ UUID fileObjectId = UuidV7Generator.generate();
+ String objectPath = objectPath(documentId);
+ String objectName = fileVersionId + (StringUtil.isEmpty(extension) ? "" : "." + extension);
+
+ FileInfo stored = fileStorageService.of(file)
+ .setPlatform(STORAGE_PLATFORM)
+ .setPath(objectPath)
+ .setSaveFilename(objectName)
+ .setOriginalFilename(originalFilename)
+ .setHashCalculatorSha256()
+ .upload();
+ if (stored == null || stored.getHashInfo() == null
+ || StringUtil.isEmpty(stored.getHashInfo().getSha256())) {
+ deleteQuietly(stored);
+ throw new DataException("SeaweedFS 涓婁紶澶辫触鎴栨湭鐢熸垚 SHA-256");
+ }
+
+ DmsFileUploadRegisterForm form = registration(folderId, sourceId, documentNo,
+ documentName, documentType, responsibleDeptId, versionLabel, preparedBy,
+ preparedOn, originalFilename, documentId, fileVersionId, fileObjectId, stored);
+ try {
+ ActionResult<DmsFileUploadVO> result = dmsResourceApi.registerUpload(SERVICE_ID, form);
+ if (result == null || !ActionResultCode.SUCCESS.getCode().equals(result.getCode())
+ || result.getData() == null) {
+ throw new DataException(result == null ? "DMS 涓婁紶鐧昏鏃犲搷搴�" : result.getMsg());
+ }
+ if (!sameStoredObject(result.getData(), stored)) {
+ deleteQuietly(stored);
+ }
+ return result.getData();
+ } catch (RuntimeException exception) {
+ deleteQuietly(stored);
+ throw exception;
+ }
+ }
+
+ public DmsFileUploadVO revise(UUID documentId, UUID baseFileVersionId, String sourceId,
+ String versionLabel, String preparedBy, LocalDate preparedOn,
+ String revisionReason, MultipartFile file) {
+ validateRevision(documentId, baseFileVersionId, sourceId, versionLabel, preparedBy,
+ preparedOn, revisionReason, file);
+ String originalFilename = safeFilename(file.getOriginalFilename());
+ String extension = UpUtil.getFileType(file);
+ if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), extension)) {
+ throw new DataException(MsgCode.FA017.get());
+ }
+
+ UUID fileVersionId = UuidV7Generator.generate();
+ UUID fileObjectId = UuidV7Generator.generate();
+ String objectPath = objectPath(documentId);
+ String objectName = fileVersionId + (StringUtil.isEmpty(extension) ? "" : "." + extension);
+
+ FileInfo stored = fileStorageService.of(file)
+ .setPlatform(STORAGE_PLATFORM)
+ .setPath(objectPath)
+ .setSaveFilename(objectName)
+ .setOriginalFilename(originalFilename)
+ .setHashCalculatorSha256()
+ .upload();
+ if (stored == null || stored.getHashInfo() == null
+ || StringUtil.isEmpty(stored.getHashInfo().getSha256())) {
+ deleteQuietly(stored);
+ throw new DataException("SeaweedFS 涓婁紶澶辫触鎴栨湭鐢熸垚 SHA-256");
+ }
+
+ DmsFileRevisionRegisterForm form = revisionRegistration(documentId, baseFileVersionId,
+ fileVersionId, fileObjectId, sourceId, versionLabel, preparedBy, preparedOn,
+ revisionReason, originalFilename, stored);
+ try {
+ ActionResult<DmsFileUploadVO> result = dmsResourceApi.registerRevision(SERVICE_ID, form);
+ if (result == null || !ActionResultCode.SUCCESS.getCode().equals(result.getCode())
+ || result.getData() == null) {
+ throw new DataException(result == null ? "DMS 淇鐧昏鏃犲搷搴�" : result.getMsg());
+ }
+ if (!sameStoredObject(result.getData(), stored)) {
+ deleteQuietly(stored);
+ }
+ return result.getData();
+ } catch (RuntimeException exception) {
+ deleteQuietly(stored);
+ throw exception;
+ }
+ }
+
+ private DmsFileUploadRegisterForm registration(UUID folderId, String sourceId,
+ String documentNo, String documentName,
+ String documentType, String responsibleDeptId,
+ String versionLabel, String preparedBy,
+ LocalDate preparedOn, String originalFilename,
+ UUID documentId,
+ UUID fileVersionId, UUID fileObjectId,
+ FileInfo stored) {
+ MinioFileStorage storage = fileStorageService.getFileStorage(STORAGE_PLATFORM);
+ HashInfo hashInfo = stored.getHashInfo();
+ DmsFileUploadRegisterForm form = new DmsFileUploadRegisterForm();
+ form.setDocumentId(documentId);
+ form.setFileVersionId(fileVersionId);
+ form.setFileObjectId(fileObjectId);
+ form.setFolderId(folderId);
+ form.setDocumentNo(documentNo.trim());
+ form.setDocumentName(documentName.trim());
+ form.setDocumentType(documentType.trim());
+ form.setResponsibleDeptId(responsibleDeptId.trim());
+ form.setVersionLabel(versionLabel.trim());
+ form.setFileName(originalFilename);
+ form.setMimeType(trimToNull(stored.getContentType()));
+ form.setSizeBytes(stored.getSize());
+ form.setChecksumSha256(hashInfo.getSha256());
+ form.setPreparedBy(preparedBy.trim());
+ form.setPreparedOn(preparedOn);
+ form.setStoragePlatform(stored.getPlatform());
+ form.setBucketName(storage.getBucketName());
+ form.setBasePath(trimToEmpty(stored.getBasePath()));
+ form.setObjectPath(stored.getPath());
+ form.setObjectName(stored.getFilename());
+ form.setSourceId(sourceId.trim());
+ return form;
+ }
+
+ private DmsFileRevisionRegisterForm revisionRegistration(UUID documentId,
+ UUID baseFileVersionId,
+ UUID fileVersionId,
+ UUID fileObjectId,
+ String sourceId,
+ String versionLabel,
+ String preparedBy,
+ LocalDate preparedOn,
+ String revisionReason,
+ String originalFilename,
+ FileInfo stored) {
+ MinioFileStorage storage = fileStorageService.getFileStorage(STORAGE_PLATFORM);
+ HashInfo hashInfo = stored.getHashInfo();
+ DmsFileRevisionRegisterForm form = new DmsFileRevisionRegisterForm();
+ form.setDocumentId(documentId);
+ form.setBaseFileVersionId(baseFileVersionId);
+ form.setFileVersionId(fileVersionId);
+ form.setFileObjectId(fileObjectId);
+ form.setVersionLabel(versionLabel.trim());
+ form.setFileName(originalFilename);
+ form.setMimeType(trimToNull(stored.getContentType()));
+ form.setSizeBytes(stored.getSize());
+ form.setChecksumSha256(hashInfo.getSha256());
+ form.setPreparedBy(preparedBy.trim());
+ form.setPreparedOn(preparedOn);
+ form.setRevisionReason(revisionReason.trim());
+ form.setStoragePlatform(stored.getPlatform());
+ form.setBucketName(storage.getBucketName());
+ form.setBasePath(trimToEmpty(stored.getBasePath()));
+ form.setObjectPath(stored.getPath());
+ form.setObjectName(stored.getFilename());
+ form.setSourceId(sourceId.trim());
+ return form;
+ }
+
+ private boolean sameStoredObject(DmsFileUploadVO registered, FileInfo stored) {
+ return Objects.equals(registered.getStoragePlatform(), stored.getPlatform())
+ && Objects.equals(registered.getBasePath(), trimToEmpty(stored.getBasePath()))
+ && Objects.equals(registered.getObjectPath(), stored.getPath())
+ && Objects.equals(registered.getObjectName(), stored.getFilename());
+ }
+
+ private String objectPath(UUID documentId) {
+ return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"))
+ + documentId + "/";
+ }
+
+ private String safeFilename(String value) {
+ if (value == null || value.trim().isEmpty()) {
+ throw new DataException("鏂囦欢鍚嶄笉鑳戒负绌�");
+ }
+ String normalized = value.replace('\\', '/');
+ String filename = Paths.get(normalized).getFileName().toString().trim();
+ if (filename.isEmpty() || filename.length() > 300) {
+ throw new DataException("鏂囦欢鍚嶉暱搴﹀繀椤诲湪 1 鍒� 300 涔嬮棿");
+ }
+ return filename;
+ }
+
+ private void validate(String sourceId, String documentNo, String documentName,
+ String documentType, String responsibleDeptId, String versionLabel,
+ String preparedBy, LocalDate preparedOn, MultipartFile file) {
+ if (file == null || file.isEmpty()) {
+ throw new DataException("涓婁紶鏂囦欢涓嶈兘涓虹┖");
+ }
+ requireText(sourceId, "sourceId", 160);
+ requireText(documentNo, "鏂囦欢缂栧彿", 200);
+ requireText(documentName, "鏂囦欢鍚嶇О", 300);
+ requireText(documentType, "鏂囦欢绫诲瀷", 100);
+ requireText(responsibleDeptId, "褰掑睘閮ㄩ棬", 100);
+ requireText(versionLabel, "鐗堟湰鍙�", 50);
+ requireText(preparedBy, "鍒跺畾浜�", 100);
+ if (preparedOn == null) {
+ throw new DataException("鍒跺畾鏃ユ湡涓嶈兘涓虹┖");
+ }
+ fileStorageService.getFileStorageVerify(STORAGE_PLATFORM);
+ }
+
+ private void validateRevision(UUID documentId, UUID baseFileVersionId, String sourceId,
+ String versionLabel, String preparedBy, LocalDate preparedOn,
+ String revisionReason, MultipartFile file) {
+ if (documentId == null || baseFileVersionId == null) {
+ throw new DataException("鏂囦欢鍙婂綋鍓嶇増鏈笉鑳戒负绌�");
+ }
+ if (file == null || file.isEmpty()) {
+ throw new DataException("淇鏂囦欢涓嶈兘涓虹┖");
+ }
+ requireText(sourceId, "sourceId", 120);
+ requireText(versionLabel, "鏂扮増鏈彿", 50);
+ requireText(preparedBy, "鍒跺畾浜�", 100);
+ requireText(revisionReason, "淇鍘熷洜", 1000);
+ if (preparedOn == null) {
+ throw new DataException("鍒跺畾鏃ユ湡涓嶈兘涓虹┖");
+ }
+ fileStorageService.getFileStorageVerify(STORAGE_PLATFORM);
+ }
+
+ private void requireText(String value, String label, int maxLength) {
+ if (value == null || value.trim().isEmpty() || value.trim().length() > maxLength) {
+ throw new DataException(label + "闀垮害蹇呴』鍦� 1 鍒� " + maxLength + " 涔嬮棿");
+ }
+ }
+
+ private String trimToEmpty(String value) {
+ return value == null ? "" : value.trim();
+ }
+
+ private String trimToNull(String value) {
+ return value == null || value.trim().isEmpty() ? null : value.trim();
+ }
+
+ private void deleteQuietly(FileInfo stored) {
+ if (stored == null) {
+ return;
+ }
+ try {
+ if (!fileStorageService.delete(stored)) {
+ log.error("DMS 涓婁紶琛ュ伩鍒犻櫎澶辫触: platform={}, path={}, filename={}",
+ stored.getPlatform(), stored.getPath(), stored.getFilename());
+ }
+ } catch (Exception exception) {
+ log.error("DMS 涓婁紶琛ュ伩鍒犻櫎寮傚父: platform={}, path={}, filename={}",
+ stored.getPlatform(), stored.getPath(), stored.getFilename(), exception);
+ }
+ }
+}
--
Gitblit v1.8.0