package jnpf.bizcommon.onlyoffice.service.impl;
|
|
import jnpf.dmsEntity.download.model.DmsFileDownloadTicket;
|
import jnpf.dmsEntity.preview.model.DmsFilePreviewTicket;
|
import jnpf.exception.DataException;
|
import jnpf.dms.DmsTicketLifecycleApi;
|
import jnpf.dms.DmsTicketLifecycleChecks;
|
import jnpf.onlyoffice.DmsDownloadPdfRequest;
|
import jnpf.util.TicketUtil;
|
import jnpf.util.JsonUtil;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.util.Locale;
|
import java.util.function.Function;
|
import java.util.function.Consumer;
|
|
@Service
|
public class DmsOnlyOfficeDownloadService {
|
private final OnlyOfficeDmsPrintRenderer renderer;
|
private final Function<String, Object> ticketReader;
|
private final Function<DmsFilePreviewTicket, String> sourceTicketIssuer;
|
private final Consumer<String> sourceTicketRevoker;
|
|
@Autowired
|
public DmsOnlyOfficeDownloadService(OnlyOfficeDmsPrintRenderer renderer, DmsTicketLifecycleApi lifecycleApi) {
|
this(renderer, ticket -> DmsTicketLifecycleChecks.download(TicketUtil.parseTicket(ticket), lifecycleApi, "jnpf-biz-common"),
|
ticket -> TicketUtil.createTicket(JsonUtil.getObjectToString(ticket), 180L),
|
TicketUtil::deleteTicket);
|
}
|
|
DmsOnlyOfficeDownloadService(OnlyOfficeDmsPrintRenderer renderer,
|
Function<String, Object> ticketReader,
|
Function<DmsFilePreviewTicket, String> sourceTicketIssuer,
|
Consumer<String> sourceTicketRevoker) {
|
this.renderer = renderer;
|
this.ticketReader = ticketReader;
|
this.sourceTicketIssuer = sourceTicketIssuer;
|
this.sourceTicketRevoker = sourceTicketRevoker;
|
}
|
|
public byte[] render(DmsDownloadPdfRequest request) {
|
if (request == null || request.getAccessTicket() == null
|
|| request.getAccessTicket().isBlank()) {
|
throw new DataException("缺少 DMS 下载票据");
|
}
|
DmsFileDownloadTicket ticket;
|
try {
|
ticket = DmsFileDownloadTicket.fromRaw(ticketReader.apply(request.getAccessTicket()));
|
} catch (RuntimeException exception) {
|
throw new DataException("DMS 下载票据无效或已过期");
|
}
|
if (!ticket.getFileVersionId().equals(request.getFileVersionId())) {
|
throw new DataException("DMS 下载票据与文件版本不匹配");
|
}
|
String lowerName = ticket.getFileName().toLowerCase(Locale.ROOT);
|
if (!lowerName.endsWith(".doc") && !lowerName.endsWith(".docx")) {
|
throw new DataException("仅支持将 Word 文件转换为 PDF 下载");
|
}
|
// Reuse the existing ticket-protected OnlyOffice source route. The public download
|
// route still requires login. Preserve DOWNLOAD watermarks; never resolve PREVIEW
|
// or PRINT settings and never expose this delegated source ticket to the caller.
|
DmsFilePreviewTicket source = new DmsFilePreviewTicket();
|
BeanUtils.copyProperties(ticket, source);
|
source.setScope(DmsFilePreviewTicket.SCOPE);
|
source.setExpiresAt(Math.min(ticket.getExpiresAt(), System.currentTimeMillis() + 180_000L));
|
String sourceTicket = sourceTicketIssuer.apply(source);
|
try {
|
return renderer.render(source, sourceTicket);
|
} finally {
|
sourceTicketRevoker.accept(sourceTicket);
|
}
|
}
|
}
|