mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
添加pdf生成器
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -71,6 +71,12 @@
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>playwright</artifactId>
|
||||
<version>1.40.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
|
||||
@@ -130,25 +130,65 @@ public class FileService extends BaseService<FileEntity, FileRepository> {
|
||||
}
|
||||
|
||||
String objectKey = fileEntity.getDirectory() + "/" + fileEntity.getObjectId();
|
||||
String objectUrl = "";
|
||||
// PutObjectResult putObjectResult =
|
||||
// obsClient.putObject(
|
||||
// hwCloudProperty.getObs().getBucketName(),
|
||||
// objectKey,
|
||||
// file.getInputStream());
|
||||
//
|
||||
// if (putObjectResult.getStatusCode() != 200) {
|
||||
// throw new BizException("上传文件失败 %s".formatted(putObjectResult.toString()));
|
||||
// }
|
||||
|
||||
// objectUrl = putObjectResult.getObjectUrl();
|
||||
fileEntity.setPublicUrl(uploadToOSS(objectKey, file.getInputStream()));
|
||||
|
||||
this.save(fileEntity);
|
||||
|
||||
return getById(fileEntity.getId());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public FileDto upload(
|
||||
InputStream file,
|
||||
String name,
|
||||
String dir,
|
||||
String sortKey,
|
||||
String code,
|
||||
String remarks) {
|
||||
FileEntity fileEntity = new FileEntity();
|
||||
fileEntity.setFileName(name);
|
||||
fileEntity.setFileSize(Long.valueOf(file.available()));
|
||||
fileEntity.setCode(code);
|
||||
fileEntity.setRemarks(remarks);
|
||||
try {
|
||||
|
||||
fileEntity.setSortKey(Integer.parseInt(sortKey));
|
||||
} catch (Exception e) {
|
||||
|
||||
fileEntity.setSortKey(1);
|
||||
}
|
||||
fileEntity.setDirectory(
|
||||
"%s/%s/%s"
|
||||
.formatted(
|
||||
activateProfile,
|
||||
Ctx.currentUser().getOrganizationId(),
|
||||
StringUtils.defaultIfBlank(dir, "public")));
|
||||
InputStream inputStream = file;
|
||||
fileEntity.setObjectId(
|
||||
UUID.randomUUID() + "." + FilenameUtils.getExtension(name.replace(":", "_")));
|
||||
try (inputStream) {
|
||||
fileEntity.setMimeType(tika.detect(inputStream));
|
||||
}
|
||||
|
||||
String objectKey = fileEntity.getDirectory() + "/" + fileEntity.getObjectId();
|
||||
|
||||
fileEntity.setPublicUrl(uploadToOSS(objectKey, file));
|
||||
|
||||
this.save(fileEntity);
|
||||
|
||||
return getById(fileEntity.getId());
|
||||
}
|
||||
|
||||
private String uploadToOSS(String objectKey, InputStream inputStream) {
|
||||
String objectUrl;
|
||||
try {
|
||||
|
||||
com.aliyun.oss.model.PutObjectResult objectResult =
|
||||
ossClient.putObject(
|
||||
aliyunProperty.getOSS().getBucketName(),
|
||||
objectKey,
|
||||
file.getInputStream());
|
||||
inputStream);
|
||||
} catch (Exception e) {
|
||||
|
||||
log.warn("上传文件失败", e);
|
||||
@@ -171,11 +211,6 @@ public class FileService extends BaseService<FileEntity, FileRepository> {
|
||||
aliyunProperty.getOSS().getBucketName(),
|
||||
ossRegion.getEndpoint(),
|
||||
objectKey);
|
||||
|
||||
fileEntity.setPublicUrl(objectUrl);
|
||||
|
||||
this.save(fileEntity);
|
||||
|
||||
return getById(fileEntity.getId());
|
||||
return objectUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.controller;
|
||||
|
||||
import cn.lihongjie.coal.annotation.OrgScope;
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.CreatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.GeneratePdfDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.PdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.UpdatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.service.PdfGeneratorService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/pdfGenerator")
|
||||
@SysLog(module = "Pdf生成器")
|
||||
@Slf4j
|
||||
@OrgScope
|
||||
public class PdfGeneratorController {
|
||||
@Autowired private PdfGeneratorService service;
|
||||
|
||||
@PostMapping("/create")
|
||||
public PdfGeneratorDto create(@RequestBody CreatePdfGeneratorDto request) {
|
||||
return this.service.create(request);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public PdfGeneratorDto update(@RequestBody UpdatePdfGeneratorDto request) {
|
||||
return this.service.update(request);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody IdRequest request) {
|
||||
this.service.delete(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PostMapping("/getById")
|
||||
public PdfGeneratorDto getById(@RequestBody IdRequest request) {
|
||||
return this.service.getById(request.getId());
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/generate")
|
||||
public PdfGeneratorDto generate(@RequestBody GeneratePdfDto request) {
|
||||
return this.service.generate(request);
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
public Page<PdfGeneratorDto> list(@RequestBody CommonQuery request) {
|
||||
return this.service.list(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CreatePdfGeneratorDto extends OrgCommonDto {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GeneratePdfDto extends OrgCommonDto {
|
||||
private String htmlUrl;
|
||||
private String htmlText;
|
||||
|
||||
private ObjectNode options;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class PdfGeneratorDto extends OrgCommonDto {
|
||||
|
||||
|
||||
private String htmlUrl;
|
||||
private String htmlText;
|
||||
|
||||
|
||||
private String pdfUrl;
|
||||
|
||||
|
||||
private LocalDateTime startTime;
|
||||
private LocalDateTime endTime;
|
||||
|
||||
private Long duration;
|
||||
|
||||
|
||||
private String options;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UpdatePdfGeneratorDto extends OrgCommonDto {}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.entity;
|
||||
|
||||
import cn.lihongjie.coal.base.entity.OrgCommonEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class PdfGeneratorEntity extends OrgCommonEntity {
|
||||
|
||||
|
||||
|
||||
private String htmlUrl;
|
||||
private String htmlText;
|
||||
|
||||
|
||||
private String pdfUrl;
|
||||
|
||||
|
||||
private LocalDateTime startTime;
|
||||
private LocalDateTime endTime;
|
||||
|
||||
private Long duration;
|
||||
|
||||
|
||||
private String options;
|
||||
|
||||
@Comment("生成状态")
|
||||
private String execStatus;
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'common.execStatus'\n"
|
||||
+ " and i.code = exec_status)")
|
||||
private String execStatusName;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.mapper;
|
||||
|
||||
import cn.lihongjie.coal.base.mapper.BaseMapper;
|
||||
import cn.lihongjie.coal.base.mapper.CommonMapper;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.CreatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.GeneratePdfDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.PdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.UpdatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.entity.PdfGeneratorEntity;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.control.DeepClone;
|
||||
|
||||
@Mapper(
|
||||
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
|
||||
uses = {CommonMapper.class},
|
||||
mappingControl = DeepClone.class)
|
||||
public interface PdfGeneratorMapper
|
||||
extends BaseMapper<
|
||||
PdfGeneratorEntity,
|
||||
PdfGeneratorDto,
|
||||
CreatePdfGeneratorDto,
|
||||
UpdatePdfGeneratorDto> {
|
||||
PdfGeneratorEntity toEntity(GeneratePdfDto request);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.repository;
|
||||
|
||||
import cn.lihongjie.coal.base.dao.BaseRepository;
|
||||
import cn.lihongjie.coal.pdfGenerator.entity.PdfGeneratorEntity;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PdfGeneratorRepository extends BaseRepository<PdfGeneratorEntity> {}
|
||||
@@ -0,0 +1,188 @@
|
||||
package cn.lihongjie.coal.pdfGenerator.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.file.dto.FileDto;
|
||||
import cn.lihongjie.coal.file.service.FileService;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.CreatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.GeneratePdfDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.PdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.dto.UpdatePdfGeneratorDto;
|
||||
import cn.lihongjie.coal.pdfGenerator.entity.PdfGeneratorEntity;
|
||||
import cn.lihongjie.coal.pdfGenerator.mapper.PdfGeneratorMapper;
|
||||
import cn.lihongjie.coal.pdfGenerator.repository.PdfGeneratorRepository;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.microsoft.playwright.Browser;
|
||||
import com.microsoft.playwright.Playwright;
|
||||
import com.microsoft.playwright.Response;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
|
||||
import lombok.Cleanup;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class PdfGeneratorService extends BaseService<PdfGeneratorEntity, PdfGeneratorRepository> {
|
||||
@Autowired FileService fileService;
|
||||
@Autowired ObjectMapper objectMapper;
|
||||
@Autowired private PdfGeneratorRepository repository;
|
||||
@Autowired private PdfGeneratorMapper mapper;
|
||||
@Autowired private ConversionService conversionService;
|
||||
private Boolean chromeInit = false;
|
||||
private Playwright playwright;
|
||||
private Browser browser;
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
log.info("销毁chrome");
|
||||
if (browser != null) {
|
||||
|
||||
browser.close();
|
||||
}
|
||||
|
||||
if (playwright != null) {
|
||||
|
||||
playwright.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public PdfGeneratorDto generate(GeneratePdfDto request) {
|
||||
|
||||
synchronized (this) {
|
||||
LocalDateTime startTime = LocalDateTime.now();
|
||||
if (!chromeInit) {
|
||||
log.info("初始化chrome");
|
||||
|
||||
playwright = Playwright.create();
|
||||
browser = playwright.chromium().launch();
|
||||
chromeInit = true;
|
||||
}
|
||||
|
||||
@Cleanup com.microsoft.playwright.Page page = browser.newPage();
|
||||
|
||||
if (StringUtils.isNotEmpty(request.getHtmlText())) {
|
||||
page.setContent(request.getHtmlText());
|
||||
} else if (StringUtils.isNotEmpty(request.getHtmlUrl())) {
|
||||
Response response = page.navigate(request.getHtmlUrl());
|
||||
|
||||
log.info("访问{}返回{}", request.getHtmlUrl(), response.status());
|
||||
} else {
|
||||
throw new IllegalArgumentException("htmlText和htmlUrl不能同时为空");
|
||||
}
|
||||
|
||||
com.microsoft.playwright.Page.PdfOptions pdfOptions = null;
|
||||
if (request.getOptions() != null) {
|
||||
pdfOptions =
|
||||
objectMapper.treeToValue(
|
||||
request.getOptions(),
|
||||
com.microsoft.playwright.Page.PdfOptions.class);
|
||||
}
|
||||
PdfGeneratorEntity entity = mapper.toEntity(request);
|
||||
boolean error = false;
|
||||
String stackTrace = null;
|
||||
byte[] pdf = null;
|
||||
try {
|
||||
|
||||
pdf = page.pdf(pdfOptions);
|
||||
} catch (Exception e) {
|
||||
|
||||
log.error("生成pdf失败", e);
|
||||
stackTrace = ExceptionUtils.getStackTrace(e);
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (pdf != null) {
|
||||
|
||||
FileDto generatePdf = null;
|
||||
try {
|
||||
|
||||
generatePdf =
|
||||
fileService.upload(
|
||||
new ByteArrayInputStream(pdf),
|
||||
request.getName(),
|
||||
"generatePdf",
|
||||
null,
|
||||
null,
|
||||
"");
|
||||
} catch (Exception e) {
|
||||
log.error("上传pdf失败", e);
|
||||
error = true;
|
||||
stackTrace = ExceptionUtils.getStackTrace(e);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
|
||||
entity.setPdfUrl(generatePdf.getPublicUrl());
|
||||
}
|
||||
}
|
||||
|
||||
entity.setEndTime(LocalDateTime.now());
|
||||
|
||||
entity.setDuration(Duration.between(startTime, entity.getEndTime()).toMillis());
|
||||
|
||||
entity.setRemarks(stackTrace);
|
||||
entity.setExecStatus(error ? "1" : "0");
|
||||
|
||||
this.save(entity);
|
||||
return this.mapper.toDto(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public PdfGeneratorDto create(CreatePdfGeneratorDto request) {
|
||||
PdfGeneratorEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public PdfGeneratorDto update(UpdatePdfGeneratorDto request) {
|
||||
PdfGeneratorEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
this.repository.deleteAllById(request.getIds());
|
||||
}
|
||||
|
||||
public PdfGeneratorDto getById(String id) {
|
||||
PdfGeneratorEntity entity = repository.get(id);
|
||||
|
||||
return mapper.toDto(entity);
|
||||
}
|
||||
|
||||
public Page<PdfGeneratorDto> list(CommonQuery query) {
|
||||
Page<PdfGeneratorEntity> page =
|
||||
repository.findAll(
|
||||
query.specification(conversionService),
|
||||
PageRequest.of(
|
||||
query.getPageNo(),
|
||||
query.getPageSize(),
|
||||
Sort.by(query.getOrders())));
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
}
|
||||
@@ -1703,6 +1703,20 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "common.execStatus",
|
||||
"name": "通用状态",
|
||||
"item": [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "成功"
|
||||
},
|
||||
{
|
||||
"code": "1",
|
||||
"name": "失败"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "loginUserHis.loginStatus",
|
||||
"name": "登录状态",
|
||||
|
||||
Reference in New Issue
Block a user