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.DmsFileUploadRegisterForm;
|
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 DmsFileUploadService {
|
private static final String SOURCE_PREFIX = "upload:";
|
|
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(DmsFileUploadRegisterForm form, String serviceId) {
|
UserInfo user = currentIdentity.requireUser();
|
String tenantId = currentIdentity.tenantId(user);
|
String sourceId = form.getSourceId().trim();
|
decisionService.requireAllowed(DmsResourceType.FOLDER, form.getFolderId(), DmsPermissionAction.CREATE);
|
|
DmsFileUploadVO existing = fileObjectMapper.selectUploadBySource(tenantId, serviceId, sourceId);
|
if (existing != null) {
|
validateRetry(existing, form);
|
return existing;
|
}
|
|
try {
|
insertDocument(form, tenantId, user.getUserId(), serviceId, sourceId);
|
insertFileVersion(form, tenantId, user.getUserId(), serviceId, sourceId);
|
insertDirectEffectiveState(form, tenantId, user.getUserId());
|
insertFileObject(form, tenantId, user.getUserId(), serviceId, sourceId);
|
} catch (DuplicateKeyException exception) {
|
throw conflict("上传登记的资源 ID、source_id、版本号或对象键已被占用", exception);
|
}
|
|
auditAdapter.dataChange("CREATE", "上传 DMS 文件", "dms_file_objects",
|
form.getFileObjectId().toString(), null,
|
"{\"documentId\":\"" + form.getDocumentId() + "\",\"fileVersionId\":\""
|
+ form.getFileVersionId() + "\"}");
|
return fileObjectMapper.selectUploadBySource(tenantId, serviceId, sourceId);
|
}
|
|
private void insertDocument(DmsFileUploadRegisterForm form, String tenantId, String userId,
|
String serviceId, String sourceId) {
|
DmsDocumentEntity document = new DmsDocumentEntity();
|
document.setId(form.getDocumentId());
|
document.setTenantId(tenantId);
|
document.setFolderId(form.getFolderId());
|
document.setDocumentNo(form.getDocumentNo().trim());
|
document.setName(form.getDocumentName().trim());
|
document.setDocumentType(form.getDocumentType().trim());
|
document.setResponsibleDeptId(form.getResponsibleDeptId().trim());
|
document.setCreatedBy(userId);
|
documentMapper.insert(document);
|
insertRegistry(tenantId, form.getDocumentId(), DmsResourceType.DOCUMENT,
|
registrySource(sourceId, "document"), serviceId);
|
}
|
|
private void insertFileVersion(DmsFileUploadRegisterForm form, String tenantId, String userId,
|
String serviceId, String sourceId) {
|
DmsFileVersionEntity version = new DmsFileVersionEntity();
|
version.setId(form.getFileVersionId());
|
version.setTenantId(tenantId);
|
version.setDocumentId(form.getDocumentId());
|
version.setVersionNo(1L);
|
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);
|
insertRegistry(tenantId, form.getFileVersionId(), DmsResourceType.FILE_VERSION,
|
registrySource(sourceId, "version:1"), serviceId);
|
}
|
|
private void insertFileObject(DmsFileUploadRegisterForm 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 insertDirectEffectiveState(DmsFileUploadRegisterForm form, String tenantId,
|
String userId) {
|
versionStateMapper.insertDirectEffective(tenantId, form.getDocumentId(),
|
form.getFileVersionId(), userId);
|
}
|
|
private void insertRegistry(String tenantId, java.util.UUID id, DmsResourceType type,
|
String sourceId, String serviceId) {
|
DmsPermissionResourceEntity registry = new DmsPermissionResourceEntity();
|
registry.setId(id);
|
registry.setTenantId(tenantId);
|
registry.setResourceType(type.name());
|
registry.setSourceType("SYSTEM");
|
registry.setSourceId(sourceId);
|
registry.setRegisteredBy(serviceId);
|
resourceMapper.insert(registry);
|
}
|
|
private void validateRetry(DmsFileUploadVO existing, DmsFileUploadRegisterForm form) {
|
if (!Objects.equals(existing.getFolderId(), form.getFolderId())
|
|| !Objects.equals(existing.getDocumentNo(), form.getDocumentNo().trim())
|
|| !Objects.equals(existing.getDocumentName(), form.getDocumentName().trim())
|
|| !Objects.equals(existing.getDocumentType(), form.getDocumentType().trim())
|
|| !Objects.equals(existing.getResponsibleDeptId(), form.getResponsibleDeptId().trim())
|
|| !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())) {
|
throw DmsPermissionException.of(DmsPermissionError.IDEMPOTENCY_CONFLICT,
|
"source_id 对应的上传内容与本次请求不一致");
|
}
|
}
|
|
private String registrySource(String sourceId, String suffix) {
|
return SOURCE_PREFIX + sourceId + ":" + suffix;
|
}
|
|
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 DmsPermissionException conflict(String message, Throwable cause) {
|
DmsPermissionException exception = DmsPermissionException.of(DmsPermissionError.SOURCE_CONFLICT, message);
|
exception.initCause(cause);
|
return exception;
|
}
|
}
|