刘光辉
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package jnpf.dmsService;
 
import jnpf.base.UserInfo;
import jnpf.dmsEntity.operationlog.entity.DmsFileOperationLogEntity;
import jnpf.dmsEntity.operationlog.enums.DmsFileOperationType;
import jnpf.dmsEntity.operationlog.vo.DmsFileOperationLogItemVO;
import jnpf.dmsEntity.operationlog.vo.DmsFileOperationLogPageVO;
import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
import jnpf.dmsEntity.permission.enums.DmsPermissionAction;
import jnpf.dmsEntity.permission.enums.DmsResourceType;
import jnpf.dmsMapper.DmsFileOperationLogMapper;
import jnpf.dmsMapper.DmsFileVersionMapper;
import jnpf.dmsPermission.DmsCurrentIdentity;
import jnpf.dmsPermission.DmsPermissionError;
import jnpf.dmsPermission.DmsPermissionException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.Collections;
import java.util.UUID;
import java.util.stream.Collectors;
 
@Service
@RequiredArgsConstructor
public class DmsFileOperationLogService {
    private static final int DEFAULT_PAGE_SIZE = 10;
    private static final int MAX_PAGE_SIZE = 50;
    private static final int MAX_KEYWORD_LENGTH = 100;
 
    private final DmsCurrentIdentity currentIdentity;
    private final DmsPermissionDecisionService decisionService;
    private final DmsFileVersionMapper fileVersionMapper;
    private final DmsFileOperationLogMapper operationLogMapper;
 
    public void recordUpload(UserInfo user, String tenantId, UUID documentId, UUID fileVersionId,
                             String fileName, String serviceId, String sourceId) {
        record(user, tenantId, documentId, fileVersionId, fileName, DmsFileOperationType.UPLOAD,
                "UPLOAD:" + serviceId + ":" + sourceId);
    }
 
    public void recordRevision(UserInfo user, String tenantId, UUID documentId, UUID fileVersionId,
                               String fileName, String serviceId, String sourceId) {
        record(user, tenantId, documentId, fileVersionId, fileName, DmsFileOperationType.REVISION,
                "REVISION:" + serviceId + ":" + sourceId);
    }
 
    public void recordView(UserInfo user, String tenantId, UUID documentId, UUID fileVersionId,
                           String fileName, UUID operationId) {
        record(user, tenantId, documentId, fileVersionId, fileName, DmsFileOperationType.VIEW,
                "VIEW:" + operationId);
    }
 
    public void recordDownload(UserInfo user, String tenantId, UUID documentId, UUID fileVersionId,
                               String fileName, UUID operationId) {
        record(user, tenantId, documentId, fileVersionId, fileName, DmsFileOperationType.DOWNLOAD,
                "DOWNLOAD:" + operationId);
    }
 
    @Transactional(readOnly = true)
    public DmsFileOperationLogPageVO page(UUID fileVersionId, String keyword,
                                          Integer requestedPage, Integer requestedSize) {
        UserInfo user = currentIdentity.requireUser();
        String tenantId = currentIdentity.tenantId(user);
        decisionService.requireAllowed(DmsResourceType.FILE_VERSION, fileVersionId,
                DmsPermissionAction.READ);
        DmsFileVersionEntity version = fileVersionMapper.selectByTenantAndId(tenantId, fileVersionId);
        if (version == null) {
            throw DmsPermissionException.of(DmsPermissionError.RESOURCE_NOT_FOUND,
                    "文件版本不存在");
        }
 
        String normalizedKeyword = normalizeKeyword(keyword);
        int currentPage = requestedPage == null || requestedPage < 1 ? 1 : requestedPage;
        int pageSize = requestedSize == null || requestedSize < 1
                ? DEFAULT_PAGE_SIZE : Math.min(requestedSize, MAX_PAGE_SIZE);
        long offset = (long) (currentPage - 1) * pageSize;
        long total = operationLogMapper.countByDocument(tenantId, version.getDocumentId(),
                normalizedKeyword);
 
        DmsFileOperationLogPageVO result = new DmsFileOperationLogPageVO();
        result.setCurrentPage(currentPage);
        result.setPageSize(pageSize);
        result.setTotal(total);
        if (offset >= total) {
            result.setList(Collections.<DmsFileOperationLogItemVO>emptyList());
            return result;
        }
        result.setList(operationLogMapper.selectByDocument(tenantId, version.getDocumentId(),
                        normalizedKeyword, pageSize, offset).stream()
                .map(this::toItem)
                .collect(Collectors.toList()));
        return result;
    }
 
    private void record(UserInfo user, String tenantId, UUID documentId, UUID fileVersionId,
                        String fileName, DmsFileOperationType type, String operationKey) {
        String operatorName = displayName(user);
        DmsFileOperationLogEntity log = new DmsFileOperationLogEntity();
        log.setTenantId(tenantId.trim());
        log.setDocumentId(documentId);
        log.setFileVersionId(fileVersionId);
        log.setOperationCode(type.name());
        log.setOperationKey(operationKey);
        log.setOperatorUserId(user.getUserId().trim());
        log.setOperatorName(operatorName);
        log.setFileName(fileName.trim());
        log.setOperationContent("用户" + operatorName + type.getActionText() + ":" + fileName.trim());
        operationLogMapper.insertIgnore(log);
    }
 
    private DmsFileOperationLogItemVO toItem(DmsFileOperationLogEntity entity) {
        DmsFileOperationLogItemVO result = new DmsFileOperationLogItemVO();
        result.setId(entity.getId());
        result.setOperationCode(entity.getOperationCode());
        result.setOperationContent(entity.getOperationContent());
        result.setOccurredAt(entity.getOccurredAt());
        return result;
    }
 
    private String displayName(UserInfo user) {
        String userName = trimToNull(user.getUserName());
        if (userName != null) {
            return userName;
        }
        String account = trimToNull(user.getUserAccount());
        return account != null ? account : user.getUserId().trim();
    }
 
    private String normalizeKeyword(String keyword) {
        String normalized = trimToNull(keyword);
        if (normalized != null && normalized.length() > MAX_KEYWORD_LENGTH) {
            throw DmsPermissionException.of(DmsPermissionError.INVALID_REQUEST,
                    "日志搜索关键字不能超过 " + MAX_KEYWORD_LENGTH + " 个字符");
        }
        return normalized;
    }
 
    private String trimToNull(String value) {
        return value == null || value.trim().isEmpty() ? null : value.trim();
    }
}