刘光辉
117 分钟以前 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 feign.Response;
import jnpf.base.ActionResult;
import jnpf.base.ActionResultCode;
import jnpf.dmsEntity.permission.enums.DmsResourceType;
import jnpf.dmsEntity.preview.form.DmsFilePreviewTicketRequest;
import jnpf.dmsEntity.preview.vo.DmsFilePageCountVO;
import jnpf.dmsEntity.preview.vo.DmsFilePreviewTicketVO;
import jnpf.dmsService.file.DmsFileContentApi;
import jnpf.onlyoffice.DmsPageCountApi;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import java.util.UUID;
 
@Service
@RequiredArgsConstructor
public class DmsFilePageCountService {
    private final DmsFilePreviewService previewService;
    private final DmsFileContentApi fileContentApi;
    private final DmsDocumentPageCountService documentPageCountService;
    private final DmsPageCountApi onlyOfficePageCountApi;
 
    public DmsFilePageCountVO getPageCount(UUID fileVersionId) throws IOException {
        DmsFilePreviewTicketVO ticket = createReadTicket(fileVersionId);
        int pageCount = readPageCount(fileVersionId, ticket);
        DmsFilePageCountVO result = new DmsFilePageCountVO();
        result.setFileVersionId(fileVersionId);
        result.setFileName(ticket.getFileName());
        result.setPageCount(pageCount);
        return result;
    }
 
    private int readPageCount(UUID fileVersionId, DmsFilePreviewTicketVO ticket) throws IOException {
        String extension = suffix(ticket.getFileName());
        if (".doc".equals(extension) || ".docx".equals(extension)) {
            ActionResult<Integer> result = onlyOfficePageCountApi.getPageCount(
                    fileVersionId, ticket.getAccessTicket());
            if (result == null || !ActionResultCode.SUCCESS.getCode().equals(result.getCode())
                    || result.getData() == null || result.getData() <= 0) {
                throw new IOException("OnlyOffice 页数查询失败,请稍后重试");
            }
            return result.getData();
        }
        if (!".pdf".equals(extension)) {
            throw new IOException("页数查询仅支持 doc、docx、pdf 文件");
        }
        Path temporaryFile = download(fileVersionId, ticket);
        try {
            return documentPageCountService.getPageCount(temporaryFile, ticket.getFileName());
        } finally {
            Files.deleteIfExists(temporaryFile);
        }
    }
 
    private DmsFilePreviewTicketVO createReadTicket(UUID fileVersionId) {
        DmsFilePreviewTicketRequest request = new DmsFilePreviewTicketRequest();
        request.setResourceType(DmsResourceType.FILE_VERSION);
        request.setResourceId(fileVersionId);
        request.setOperationId(UUID.randomUUID());
        return previewService.createTicket(request);
    }
 
    private Path download(UUID fileVersionId, DmsFilePreviewTicketVO ticket) throws IOException {
        Response response = fileContentApi.stream(fileVersionId, ticket.getAccessTicket());
        if (response == null || response.status() < 200 || response.status() >= 300
                || response.body() == null) {
            if (response != null) {
                response.close();
            }
            throw new IOException("文件服务读取失败");
        }
 
        Path target = Files.createTempFile("dms-page-count-", suffix(ticket.getFileName()));
        try {
            copy(response, target);
            return target;
        } catch (IOException exception) {
            Files.deleteIfExists(target);
            throw exception;
        }
    }
 
    private void copy(Response response, Path target) throws IOException {
        byte[] buffer = new byte[64 * 1024];
        try (Response ignored = response;
             InputStream input = response.body().asInputStream();
             OutputStream output = Files.newOutputStream(target)) {
            int read;
            while ((read = input.read(buffer)) >= 0) {
                output.write(buffer, 0, read);
            }
        }
    }
 
    private String suffix(String fileName) {
        int separator = fileName == null ? -1 : fileName.lastIndexOf('.');
        if (separator < 0) {
            return ".bin";
        }
        String value = fileName.substring(separator).toLowerCase(Locale.ROOT);
        return value.matches("\\.[a-z0-9]{1,10}") ? value : ".bin";
    }
}