package jnpf.bizcommon.onlyoffice.service.impl;
|
|
import jnpf.base.UserInfo;
|
import jnpf.bizcommon.onlyoffice.entity.DmsPrintRenderItem;
|
import jnpf.bizcommon.onlyoffice.entity.DmsPrintRenderRequest;
|
import jnpf.bizcommon.onlyoffice.entity.OnlyOfficeProperties;
|
import jnpf.dmsEntity.preview.model.DmsFilePreviewTicket;
|
import jnpf.exception.DataException;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.ObjectUtils;
|
|
import java.util.ArrayList;
|
import java.util.HashSet;
|
import java.util.LinkedHashSet;
|
import java.util.List;
|
import java.util.Set;
|
import java.util.UUID;
|
|
@Service
|
@RequiredArgsConstructor
|
public class DmsOnlyOfficePrintService {
|
private final DmsOnlyOfficePrintTicketValidator validator;
|
private final OnlyOfficeDmsPrintRenderer renderer;
|
private final DmsOnlyOfficePrintPdfComposer composer;
|
private final OnlyOfficeProperties properties;
|
|
public byte[] render(DmsPrintRenderRequest request, UserInfo user) {
|
List<DmsPrintRenderItem> items = items(request);
|
UUID fileVersionId = items.get(0).getFileVersionId();
|
String fileName = items.get(0).getFileName();
|
Set<String> accessTickets = new HashSet<>();
|
List<DmsFilePreviewTicket> tickets = new ArrayList<>(items.size());
|
for (DmsPrintRenderItem item : items) {
|
if (!fileVersionId.equals(item.getFileVersionId())
|
|| !fileName.equals(item.getFileName())
|
|| !accessTickets.add(item.getAccessTicket())) {
|
throw new DataException("批量打印必须使用同一文件且每份使用独立票据");
|
}
|
DmsFilePreviewTicket ticket = validator.validate(item, user);
|
applyPageSubset(ticket, item.getPrintPages());
|
tickets.add(ticket);
|
}
|
DmsPrintRenderItem sourceItem = request.sourceItem();
|
DmsFilePreviewTicket sourceTicket;
|
if (sameItem(sourceItem, items.get(0))) {
|
sourceTicket = tickets.get(0);
|
} else {
|
sourceTicket = validator.validate(sourceItem, user);
|
if (!fileVersionId.equals(sourceItem.getFileVersionId())
|
|| !fileName.equals(sourceItem.getFileName())) {
|
throw new DataException("基础打印文件与批次文件不一致");
|
}
|
}
|
byte[] basePdf = renderer.renderBase(sourceTicket, sourceItem.getAccessTicket());
|
return composer.compose(basePdf, tickets);
|
}
|
|
private List<DmsPrintRenderItem> items(DmsPrintRenderRequest request) {
|
if (request == null) {
|
throw new DataException("缺少 DMS 打印转换参数");
|
}
|
boolean hasItems = request.getItems() != null;
|
boolean hasLegacy = request.getFileVersionId() != null
|
|| !ObjectUtils.isEmpty(request.getFileName())
|
|| !ObjectUtils.isEmpty(request.getAccessTicket());
|
if (hasItems == hasLegacy) {
|
throw new DataException("单份打印参数和批量打印 items 必须且只能使用一种");
|
}
|
List<DmsPrintRenderItem> items = hasItems
|
? request.getItems() : List.of(request.legacyItem());
|
if (items.isEmpty() || items.size() > properties.getDmsPrint().getMaxBatchItems()) {
|
throw new DataException("批量打印份数超过系统限制");
|
}
|
for (DmsPrintRenderItem item : items) {
|
if (item == null || item.getFileVersionId() == null
|
|| ObjectUtils.isEmpty(item.getFileName())
|
|| ObjectUtils.isEmpty(item.getAccessTicket())) {
|
throw new DataException("DMS 打印转换参数不完整");
|
}
|
}
|
return items;
|
}
|
|
private boolean sameItem(DmsPrintRenderItem left, DmsPrintRenderItem right) {
|
return left != null && right != null
|
&& java.util.Objects.equals(left.getFileVersionId(), right.getFileVersionId())
|
&& java.util.Objects.equals(left.getFileName(), right.getFileName())
|
&& java.util.Objects.equals(left.getAccessTicket(), right.getAccessTicket());
|
}
|
|
private void applyPageSubset(DmsFilePreviewTicket ticket, String requestedPages) {
|
if (ObjectUtils.isEmpty(requestedPages)) return;
|
Set<Integer> requested = parsePages(requestedPages);
|
if (!ObjectUtils.isEmpty(ticket.getPrintPages())
|
&& !parsePages(ticket.getPrintPages()).containsAll(requested)) {
|
throw new DataException("批次打印页码超出票据授权范围");
|
}
|
ticket.setPrintPages(requestedPages.trim());
|
}
|
|
private Set<Integer> parsePages(String value) {
|
Set<Integer> pages = new LinkedHashSet<>();
|
for (String raw : value.split(",", -1)) {
|
String token = raw.trim();
|
if (!token.matches("\\d+(?:\\s*-\\s*\\d+)?")) {
|
throw new DataException("批次打印页码格式无效");
|
}
|
String[] bounds = token.split("\\s*-\\s*");
|
int start;
|
int end;
|
try {
|
start = Integer.parseInt(bounds[0]);
|
end = bounds.length == 1 ? start : Integer.parseInt(bounds[1]);
|
} catch (NumberFormatException exception) {
|
throw new DataException("批次打印页码格式无效");
|
}
|
if (start < 1 || end < start || end - start + 1L + pages.size()
|
> properties.getDmsPrint().getMaxPages()) {
|
throw new DataException("批次打印页码超过系统限制");
|
}
|
for (int page = start; page <= end; page++) pages.add(page);
|
}
|
return pages;
|
}
|
|
}
|