Commit bf538617 authored by 王飞's avatar 王飞

Merge branch 'dev' into wangfei

parents 6fb54773 d296bfae
......@@ -2,6 +2,10 @@ package com.ruoyi.mapper;
import com.ruoyi.domain.ReviewTaskInbox;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author wangfei
......@@ -9,8 +13,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @createDate 2023-12-26 09:55:39
* @Entity com.ruoyi.domain.SystemReviewTaskInbox
*/
@Repository
public interface ReviewTaskInboxMapper extends BaseMapper<ReviewTaskInbox> {
List<ReviewTaskInbox> findConfirmListByTaskId(@Param("taskId") Long taskId);
List<ReviewTaskInbox> findConfirmList(@Param("reviewTaskId") Long reviewTaskId, @Param("detailsId") Long detailsId);
}
......
package com.ruoyi.service;
import com.itextpdf.text.Document;
import com.ruoyi.domain.Book;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.List;
/**
......@@ -19,4 +22,19 @@ public interface BookService extends IService<Book> {
List<Book> selectBookListException(String name);
/**
* 生成PDF
* @param os
* @return
* @throws Exception
*/
Document generateItextPdfDocument(OutputStream os) throws Exception;
/**
* 以模板生成
* @param response
* @throws Exception
*/
void generateTempPDF(HttpServletResponse response) throws Exception;
}
......@@ -2,6 +2,7 @@ package com.ruoyi.service;
import com.ruoyi.domain.ReviewTaskInbox;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.web.request.ReviewTaskInboxConfirmRequest;
/**
* @author wangfei
......@@ -16,4 +17,6 @@ public interface ReviewTaskInboxService extends IService<ReviewTaskInbox> {
*/
void saveNotify(Long reviewSceneChangeTaskId, String type);
void confirm(ReviewTaskInboxConfirmRequest request);
}
package com.ruoyi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.codec.Base64;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.PdfUtils;
import com.ruoyi.domain.Book;
import com.ruoyi.service.BookService;
import com.ruoyi.mapper.BookMapper;
......@@ -9,9 +13,19 @@ import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author wangfei
......@@ -38,6 +52,178 @@ public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements Bo
}
return null;
}
@Override
public Document generateItextPdfDocument(OutputStream os) throws Exception {
// document
Document document = new Document(PageSize.A4);
PdfWriter.getInstance(document, os);
// open
document.open();
// add content - pdf meta information
document.addAuthor("pdai");
document.addCreationDate();
document.addTitle("pdai-pdf-itextpdf");
document.addKeywords("pdf-pdai-keyword");
document.addCreator("pdai");
// add content - page content
// Title
document.add(PdfUtils.createTitle("Java 全栈知识体系"));
// Chapter 1
document.add(PdfUtils.createChapterH1("1. 知识准备"));
document.add(PdfUtils.createChapterH2("1.1 什么是POI"));
document.add(PdfUtils.createParagraph("Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。更多请参考[官方文档](https://poi.apache.org/index.html)"));
document.add(PdfUtils.createChapterH2("1.2 POI中基础概念"));
document.add(PdfUtils.createParagraph("生成xls和xlsx有什么区别?POI对Excel中的对象的封装对应关系?"));
// Chapter 2
document.add(PdfUtils.createChapterH1("2. 实现案例"));
document.add(PdfUtils.createChapterH2("2.1 用户列表示例"));
document.add(PdfUtils.createParagraph("以导出用户列表为例"));
// 表格
PdfPTable table = new PdfPTable(new float[]{20, 40, 50, 40, 40});
table.setTotalWidth(500);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
for (int i = 0; i < 5; i++) {
table.addCell(PdfUtils.createCell("1"));
table.addCell(PdfUtils.createCell("2"));
table.addCell(PdfUtils.createCell("3"));
table.addCell(PdfUtils.createCell("4"));
table.addCell(PdfUtils.createCell("5"));
}
document.add(table);
document.add(PdfUtils.createChapterH2("2.2 图片导出示例"));
document.add(PdfUtils.createParagraph("以导出图片为例"));
// 图片
Image image = Image.getInstance("C:/Users/gxk/Pictures/Saved Pictures/nvm.png");
image.setAlignment(Element.ALIGN_CENTER);
// 缩放
image.scalePercent(60);
document.add(image);
// close
document.close();
return document;
}
@Override
public void generateTempPDF(HttpServletResponse response) throws Exception {
PdfReader reader = null;
PdfStamper ps = null;
OutputStream fos = null;
ByteArrayOutputStream bos = null;
Base64.InputStream fin = null;
ServletOutputStream out = null;
try {
// 模板绝对路径--服务器
String fileName = "/template/receipt_template.pdf";
// 读取现有模板内容
reader = new PdfReader(fileName);
// 创建输出流
bos = new ByteArrayOutputStream();
// 实例化PdfStamper准备编辑pdf内容
ps = new PdfStamper(reader, bos);
// 获取表单所有元素
AcroFields fields = ps.getAcroFields();
// 设置具体字体格式的编码, 不设置的话中文可能不会显示
BaseFont bf = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
fields.addSubstitutionFont(bf);
// 动态添加所需要的数据,key跟模板中对应文本域名称一致
Map<String, String> map = new HashMap<>();
map.put("code", "1234567890fjdksjfdsfdsffdsjfdssssssttttttttttttttt");
map.put("table_image", "C:/Users/gxk/Pictures/Saved Pictures/nvm.png");
// 渲染
fillData(fields, map, ps);
//必须要调用这个,否则文档不会生成的
ps.setFormFlattening(true);
if(ps != null){
ps.close();
}
//生成pdf路径存放的路径
fos = response.getOutputStream();
fos.write(bos.toByteArray());
}catch (Exception e){
e.printStackTrace();
}finally {
if(fos!=null){
fos.flush();
fos.close();
}
if (bos != null){
bos.close();
}
if(reader != null){
reader.close();
}
}
}
/**
* 填充模板中的数据
* @param fields
* @param data 是一个Map<String,String> 主要存储 key 表单模板中的单元格名 value为想要赋的值,遍历
* @param ps
*/
public void fillData(AcroFields fields, Map<String, String> data, PdfStamper ps) {
try {
for (String key : data.keySet()) {
String value = data.get(key);
if (key.contains("image")) {
addImageToPdf(key, fields, ps, value);
continue;
}
// 为字段赋值,注意字段名称是区分大小写的
fields.setField(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 添加图片
* @param key 应为模板名
* @param form 动态字段
* @param stamper
* @param filePath 本地图片路径
* @throws DocumentException
* @throws IOException
* @throws IOException
*/
private static void addImageToPdf(String key,AcroFields form, PdfStamper stamper, String filePath) throws DocumentException, IOException, IOException {
// 通过图片域名获取所在页和坐标,左下角为起点
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 读图片
Image image = Image.getInstance(filePath);
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth() * 2, signRect.getHeight());
// 添加图片并设置位置(个人通过此设置使得图片垂直水平居中,可参考,具体情况已实际为准)
image.setAbsolutePosition(x, y);
under.addImage(image);
}
}
......
......@@ -11,6 +11,7 @@ import com.ruoyi.service.CarReviewTaskService;
import com.ruoyi.service.ReviewTaskInboxService;
import com.ruoyi.mapper.ReviewTaskInboxMapper;
import com.ruoyi.service.SystemReviewTaskService;
import com.ruoyi.web.request.ReviewTaskInboxConfirmRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -33,6 +34,9 @@ public class ReviewTaskInboxServiceImpl extends ServiceImpl<ReviewTaskInboxMappe
@Autowired
private CarReviewTaskService carReviewTaskService;
@Autowired
private ReviewTaskInboxMapper reviewTaskInboxMapper;
/**
* 保存场景变更对进行中的问卷产生的影响,用于提醒问卷使用者场景发生了变更。
* 体系审查任务、侧性审查任务分别查询不同的表
......@@ -54,6 +58,17 @@ public class ReviewTaskInboxServiceImpl extends ServiceImpl<ReviewTaskInboxMappe
}
@Override
public void confirm(ReviewTaskInboxConfirmRequest request) {
List<ReviewTaskInbox> inboxList = reviewTaskInboxMapper.findConfirmList(request.getReviewTaskId(),request.getDetailsId());
for (ReviewTaskInbox inbox : inboxList) {
inbox.setIsConfirm(1);
reviewTaskInboxMapper.updateById(inbox);
}
}
public void doSaveNotifyByCarReview(Long reviewSceneChangeTaskId) {
// 查找所有受变更影响的体系审查任务(所有PENDING状态的任务)
......
......@@ -5,10 +5,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.domain.*;
import com.ruoyi.mapper.CarReviewTaskMapper;
import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.SystemReviewTaskMapper;
import com.ruoyi.mapper.*;
import com.ruoyi.service.ReviewDetailsResultService;
import com.ruoyi.service.ReviewSceneChangeTaskService;
import com.ruoyi.service.ReviewStandardService;
......@@ -53,6 +50,9 @@ public class StrategyCarReviewTaskPending implements StrategyCarReviewTask, Init
@Autowired
private ReviewDetailsMapper reviewDetailsMapper;
@Autowired
private ReviewTaskInboxMapper reviewTaskInboxMapper;
// PENDING状态下
// 1.standard字段查询当前最新问卷
// 2.查询场景变更任务
......@@ -91,10 +91,12 @@ public class StrategyCarReviewTaskPending implements StrategyCarReviewTask, Init
@Override
public void doConfirmReview(CarReviewTask carReviewTask) {
List<ReviewDetails> detailsList = reviewDetailsMapper.findNoResult(carReviewTask.getId());
List<ReviewTaskInbox> inboxList = reviewTaskInboxMapper.findConfirmListByTaskId(carReviewTask.getId());
if (detailsList != null) {
throw new ServiceException("存在未填写的问卷,请填写完整", HttpStatus.ERROR, detailsList);
} else {
}else if (inboxList != null ) {
throw new ServiceException("存在未确认的场景变更信息,请确认", HttpStatus.ERROR);
}else {
// 1. 获取最新问卷
List<ReviewStandard> standardTree = reviewStandardService.findTree(carReviewTask.getStandardId(), ReviewStandard.TYPE_CAR);
......
......@@ -7,6 +7,7 @@ import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.domain.*;
import com.ruoyi.mapper.ReviewDetailsMapper;
import com.ruoyi.mapper.ReviewDetailsResultMapper;
import com.ruoyi.mapper.ReviewTaskInboxMapper;
import com.ruoyi.mapper.SystemReviewTaskMapper;
import com.ruoyi.service.*;
import com.ruoyi.web.response.SystemReviewTaskViewResponse;
......@@ -49,6 +50,9 @@ public class StrategySystemReviewTaskPending implements StrategySystemReviewTask
@Autowired
private ReviewDetailsMapper reviewDetailsMapper;
@Autowired
private ReviewTaskInboxMapper reviewTaskInboxMapper;
@Override
public void doStart(SystemReviewTask systemReviewTask) {
throw new ServiceException("不能开始一个已经开始的任务", HttpStatus.ERROR);
......@@ -70,8 +74,11 @@ public class StrategySystemReviewTaskPending implements StrategySystemReviewTask
public void doConfirm(SystemReviewTask systemReviewTask) {
// TODO
List<ReviewDetails> detailsList = reviewDetailsMapper.findNoResult(systemReviewTask.getId());
List<ReviewTaskInbox> inboxList = reviewTaskInboxMapper.findConfirmListByTaskId(systemReviewTask.getId());
if (detailsList != null) {
throw new ServiceException("存在未填写的问卷,请填写完整", HttpStatus.ERROR, detailsList);
} else if (inboxList != null){
throw new ServiceException("存在未确认的场景变更信息,请确认", HttpStatus.ERROR);
} else {
// 1. 获取最新问卷
List<ReviewStandard> standardTree = reviewStandardService.findTree(systemReviewTask.getStandardId(), ReviewStandard.TYPE_SYSTEM);
......
package com.ruoyi.web;
import com.itextpdf.text.Document;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
......@@ -9,6 +11,7 @@ import com.ruoyi.web.request.BookDeleteRequest;
import com.ruoyi.web.request.BookListRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
......@@ -16,6 +19,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
......@@ -73,4 +78,17 @@ public class BookController extends BaseController {
return getDataTable(books);
}
@Anonymous
@ApiOperation("Download")
@GetMapping(value = "/download", produces = "application/json")
public void download(HttpServletResponse response) {
response.setHeader("content-disposition","attachment;fileName="+"ReceiptPrinter.pdf");
try {
// bookService.generateItextPdfDocument(response.getOutputStream());
bookService.generateTempPDF(response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.ruoyi.web;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.service.ReviewTaskInboxService;
import com.ruoyi.web.request.ReviewTaskInboxConfirmRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "审查问卷收件箱")
@RestController
@RequestMapping("/review/task/inbox")
public class ReviewTaskInboxController extends BaseController {
@Autowired
private ReviewTaskInboxService reviewTaskInboxService;
@ApiOperation("确认信息")
@Trace
@Tags({@Tag(key = "param", value = "arg[0]"), @Tag(key = "result", value = "returnedObj")})
@Log(title = "确认多条信息", businessType = BusinessType.UPDATE)
@RequestMapping(method = RequestMethod.POST, value = "/confirm")
public R<String> confirm(@Validated @RequestBody ReviewTaskInboxConfirmRequest request) {
reviewTaskInboxService.confirm(request);
return R.ok();
}
}
package com.ruoyi.web.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel(value = "ReviewTaskInboxConfirmRequest", description = "确认信息")
@Data
public class ReviewTaskInboxConfirmRequest {
@ApiModelProperty(value = "审查任务id")
private Long reviewTaskId;
@ApiModelProperty("细则Id")
private Long detailsId;
}
......@@ -12,6 +12,17 @@
</resultMap>
<sql id="Base_Column_List">
id,review_task_id,review_scene_change_task_id,is_confirm
select id,review_task_id,review_scene_change_task_id,is_confirm from t_review_task_inbox
</sql>
<select id="findConfirmListByTaskId" resultType="com.ruoyi.domain.ReviewTaskInbox">
select id,review_task_id,review_scene_change_task_id,is_confirm from t_review_task_inbox
where review_task_id = #{taskId} and is_confirm = 0
</select>
<select id="findConfirmList" resultType="com.ruoyi.domain.ReviewTaskInbox">
SELECT inbox.id, inbox.review_task_id, inbox.is_confirm, inbox.review_scene_change_task_id, task.details_id FROM t_review_task_inbox inbox
LEFT JOIN t_review_scene_change_task task ON inbox.review_scene_change_task_id = task.id
WHERE review_task_id = #{reviewTaskId} AND task.details_id = #{detailsId} and inbox.is_confirm = 0
</select>
</mapper>
......@@ -52,13 +52,13 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- JSON工具类 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
......@@ -158,6 +158,17 @@
<version>3.0.3</version>
</dependency>
<!-- PDF -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
</project>
package com.ruoyi.common.utils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import java.io.IOException;
/**
* PDF工具类
* @author gxk
*/
public class PdfUtils {
/**
* 标题
* @param content
* @return
* @throws IOException
* @throws DocumentException
*/
public static Paragraph createTitle(String content) throws IOException, DocumentException {
Font font = new Font(getBaseFont(), 24, Font.BOLD);
Paragraph paragraph = new Paragraph(content, font);
paragraph.setAlignment(Element.ALIGN_CENTER);
return paragraph;
}
/**
* H1标题
* @param content
* @return
* @throws IOException
* @throws DocumentException
*/
public static Paragraph createChapterH1(String content) throws IOException, DocumentException {
Font font = new Font(getBaseFont(), 22, Font.BOLD);
Paragraph paragraph = new Paragraph(content, font);
paragraph.setAlignment(Element.ALIGN_LEFT);
return paragraph;
}
/**
* H2标题
* @param content
* @return
* @throws IOException
* @throws DocumentException
*/
public static Paragraph createChapterH2(String content) throws IOException, DocumentException {
Font font = new Font(getBaseFont(), 18, Font.BOLD);
Paragraph paragraph = new Paragraph(content, font);
paragraph.setAlignment(Element.ALIGN_LEFT);
return paragraph;
}
/**
* 段
* @param content
* @return
* @throws IOException
* @throws DocumentException
*/
public static Paragraph createParagraph(String content) throws IOException, DocumentException {
Font font = new Font(getBaseFont(), 12, Font.NORMAL);
Paragraph paragraph = new Paragraph(content, font);
paragraph.setAlignment(Element.ALIGN_LEFT);
// 设置左缩进
paragraph.setIndentationLeft(12);
// 设置右缩进
paragraph.setIndentationRight(12);
// 设置首行缩进
paragraph.setFirstLineIndent(24);
// 行间距
paragraph.setLeading(20f);
// 设置段落上空白
paragraph.setSpacingBefore(5f);
// 设置段落下空白
paragraph.setSpacingAfter(10f);
return paragraph;
}
/**
* 表格内容
* @param content
* @return
* @throws IOException
* @throws DocumentException
*/
public static PdfPCell createCell(String content) throws IOException, DocumentException {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
Font font = new Font(getBaseFont(), 12, Font.NORMAL);
cell.setPhrase(new Phrase(content, font));
return cell;
}
/**
* 字体
* @return
* @throws IOException
* @throws DocumentException
*/
public static BaseFont getBaseFont() throws IOException, DocumentException {
return BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment