刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package jnpf.dmsService;
 
import jnpf.audit.sdk.annotation.AuditLog;
import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
import jnpf.dmsEntity.storage.form.DmsFileLifecycleUpdateForm;
import jnpf.dmsEntity.storage.vo.DmsFileLifecycleUpdateVO;
import jnpf.dmsIntegration.audit.DmsVersionStateAuditRow;
import jnpf.dmsMapper.DmsDocumentMapper;
import jnpf.dmsMapper.DmsFileVersionMapper;
import jnpf.dmsMapper.DmsVersionStateMapper;
import jnpf.exception.DataException;
import jnpf.dmsService.expiry.DmsFileExpiryProjection;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.Date;
import java.util.UUID;
 
@Service
@RequiredArgsConstructor
public class DmsFileLifecycleService {
    private static final String EFFECTIVE = "EFFECTIVE";
    private static final String EXPIRED = "EXPIRED";
    private static final String DEFAULT_EXPIRED_REASON = "文件有效期已到,生命周期自动转为已过期";
 
    private final DmsFileVersionMapper fileVersionMapper;
    private final DmsDocumentMapper documentMapper;
    private final DmsVersionStateMapper versionStateMapper;
    private final DmsFileExpiryProjection projection;
    private final DmsBusinessLifecycleGuard businessOccupancy;
 
    @Transactional(rollbackFor = Exception.class)
    @AuditLog(action = "UPDATE", label = "同步文件到期状态", bizModule = "DMS",
            bizType = "DMS_FILE_VERSION", bizCodeExpr = "", bizCodeRequired = false,
            targetTable = "dms_version_states", targetIdExpr = "#p0.fileVersionId",
            extraExpr = "{'tenantId': #p0.tenantId, 'lifecycleStatus': #p0.lifecycleStatus, "
                    + "'effectiveFrom': #p0.effectiveFrom, 'effectiveTo': #p0.effectiveTo}")
    public DmsFileLifecycleUpdateVO updateExpired(DmsFileLifecycleUpdateForm form,
                                                   String serviceId) {
        if (form == null || form.getTenantId() == null || form.getTenantId().isBlank()
                || form.getFileVersionId() == null || form.getLifecycleStatus() == null
                || serviceId == null || serviceId.isBlank()) {
            throw new DataException("到期同步缺少租户、版本、状态或操作来源");
        }
        String tenantId = form.getTenantId().trim();
        String lifecycleStatus = form.getLifecycleStatus().trim();
        if (!EXPIRED.equals(lifecycleStatus)) throw new DataException("到期同步仅支持EXPIRED状态");
 
        if (!businessOccupancy.tryEnterExpiry(tenantId, form.getFileVersionId()))
            throw new DataException("文件业务占用或版本映射尚未释放,到期同步等待后重试");
 
        DmsFileVersionEntity version = fileVersionMapper.selectByTenantAndId(
                tenantId, form.getFileVersionId());
        if (version == null) {
            throw new DataException("文件版本不存在:" + form.getFileVersionId());
        }
        if (documentMapper.selectByTenantAndIdForUpdate(tenantId, version.getDocumentId()) == null) {
            throw new DataException("文件所属文档不存在:" + version.getDocumentId());
        }
 
        DmsVersionStateAuditRow state = versionStateMapper.selectAuditState(
                tenantId, form.getFileVersionId());
        if (state == null) {
            throw new DataException("文件生命周期状态不存在:" + form.getFileVersionId());
        }
        Date effectiveFrom = state.getEffectiveFrom();
        Date effectiveTo = state.getEffectiveTo();
        if (effectiveFrom == null || effectiveTo == null || !effectiveTo.after(effectiveFrom)) {
            throw new DataException("中心未登记合法的有限有效期,不能自动过期");
        }
        if (form.getEffectiveTo() != null && !sameInstant(effectiveTo, form.getEffectiveTo())) {
            throw new DataException("到期请求与中心已登记有效期不一致,请重新读取后重试");
        }
        if (EXPIRED.equals(state.getLifecycleStatus())) {
            projection.apply(tenantId, form.getFileVersionId(), effectiveTo, serviceId);
            return result(form.getFileVersionId(), effectiveFrom, effectiveTo);
        }
        if (!EFFECTIVE.equals(state.getLifecycleStatus())) {
            throw new DataException("文件当前生命周期状态不允许转为EXPIRED:" + state.getLifecycleStatus());
        }
 
        String reason = trimToNull(form.getStatusReason());
        int updated = versionStateMapper.expire(
                tenantId, form.getFileVersionId(),
                reason == null ? DEFAULT_EXPIRED_REASON : reason, serviceId);
        if (updated != 1) {
            throw new DataException("文件到期状态同步失败,请重试:" + form.getFileVersionId());
        }
        projection.apply(tenantId, form.getFileVersionId(), state.getEffectiveTo(), serviceId);
        return result(form.getFileVersionId(), effectiveFrom, effectiveTo);
    }
 
    private DmsFileLifecycleUpdateVO result(UUID fileVersionId, Date effectiveFrom,
                                             Date effectiveTo) {
        DmsFileLifecycleUpdateVO result = new DmsFileLifecycleUpdateVO();
        result.setFileVersionId(fileVersionId);
        result.setLifecycleStatus(EXPIRED);
        result.setEffectiveFrom(effectiveFrom);
        result.setEffectiveTo(effectiveTo);
        return result;
    }
 
    private boolean sameInstant(Date first, Date second) {
        return first != null && second != null && first.getTime() == second.getTime();
    }
 
    private String trimToNull(String value) {
        return value == null || value.trim().isEmpty() ? null : value.trim();
    }
}