package jnpf.bizcommon.onlyoffice.service.impl; import jnpf.dmsEntity.preview.model.DmsFilePreviewTicket; import jnpf.exception.DataException; import jnpf.util.TicketUtil; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.Locale; import java.util.UUID; import java.util.function.Function; /** Counts the physical pages rendered from the same protected source used by the preview. */ @Service public class DmsOnlyOfficePageCountService { private final OnlyOfficeDmsPrintRenderer renderer; private final Function ticketReader; @Autowired public DmsOnlyOfficePageCountService(OnlyOfficeDmsPrintRenderer renderer) { this(renderer, TicketUtil::parseTicket); } DmsOnlyOfficePageCountService(OnlyOfficeDmsPrintRenderer renderer, Function ticketReader) { this.renderer = renderer; this.ticketReader = ticketReader; } public int getPageCount(UUID fileVersionId, String accessTicket) { if (fileVersionId == null || accessTicket == null || accessTicket.isBlank()) { throw new DataException("缺少页数查询文件版本或预览票据"); } DmsFilePreviewTicket ticket; try { ticket = DmsFilePreviewTicket.fromRaw(ticketReader.apply(accessTicket)); } catch (RuntimeException exception) { throw new DataException("DMS 预览票据无效或已过期"); } if (!DmsFilePreviewTicket.SCOPE.equals(ticket.getScope()) || !fileVersionId.equals(ticket.getFileVersionId())) { throw new DataException("页数查询票据与文件版本或预览用途不匹配"); } String name = ticket.getFileName().toLowerCase(Locale.ROOT); if (!name.endsWith(".doc") && !name.endsWith(".docx")) { throw new DataException("OnlyOffice 页数查询仅支持 doc、docx 文件"); } // Keep preview preparation, approval pages and watermarks identical to the editor. // Do not issue a PRINT ticket or use printBase, which changes the preview source. byte[] pdf = renderer.render(ticket, accessTicket); try (PDDocument document = Loader.loadPDF(pdf)) { int pages = document.getNumberOfPages(); if (pages < 1) { throw new DataException("OnlyOffice 排版结果没有有效页面"); } return pages; } catch (IOException exception) { throw new DataException("无法读取 OnlyOffice 排版结果页数"); } } }