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";
|
}
|
}
|