zhuo
2025-05-07 a4ee8b2e144ae1118ff714554911b7d34705416e
导出添加自定义签名功能
已修改9个文件
已添加2个文件
148 ■■■■ 文件已修改
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessReportController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/dto/ProcessReportDto.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessReportMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessReport.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/ProcessReportService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessReportServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/resources/mapper/ProcessReportMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/resources/static/report-deal.docx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/SignatureImageUtil.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/resources/ttf/signature.ttf 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessReportController.java
@@ -34,7 +34,7 @@
    @ApiOperation(value = "查询检验报告发放登记列表")
    @GetMapping("/pageProcessReport")
    public Result pageProcessReport(ProcessReport processReport , Page page) {
    public Result pageProcessReport(ProcessReportDto processReport , Page page) {
        return Result.success(processReportService.pageProcessReport(page, processReport));
    }
cnas-process/src/main/java/com/ruoyi/process/dto/ProcessReportDto.java
@@ -1,6 +1,9 @@
package com.ruoyi.process.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.deepoove.poi.data.PictureRenderData;
import com.ruoyi.process.pojo.ProcessReport;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@@ -10,4 +13,18 @@
public class ProcessReportDto extends ProcessReport {
    private List<Integer> ids;
    @ApiModelProperty("发送人姓名")
    private String sendUserName;
    @ApiModelProperty("发送人地址")
    private String sendUserUrl;
    @ApiModelProperty("发送人签名")
    private PictureRenderData sendUserRender;
    @ApiModelProperty("签收签名")
    private PictureRenderData signatoryRender;
}
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessReportMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.process.dto.ProcessReportDto;
import com.ruoyi.process.pojo.ProcessReport;
import org.apache.ibatis.annotations.Param;
@@ -19,7 +20,7 @@
 */
public interface ProcessReportMapper extends BaseMapper<ProcessReport> {
    IPage<ProcessReport> pageProcessReport(Page page, @Param("ew") QueryWrapper<ProcessReport> queryWrappers);
    IPage<ProcessReportDto> pageProcessReport(Page page, @Param("ew") QueryWrapper<ProcessReportDto> queryWrappers);
    List<ProcessReport> exportProcessReport();
    List<ProcessReportDto> exportProcessReport();
}
cnas-process/src/main/java/com/ruoyi/process/pojo/ProcessReport.java
@@ -54,19 +54,8 @@
    @ApiModelProperty("发送人")
    private Integer sendUser;
    @TableField(select = false,exist = false)
    private String sendUserName;
    @ApiModelProperty("签收人")
    private String signatory;
    @TableField(select = false,exist = false)
    private String signatoryUrl;
    @TableField(select = false,exist = false)
    private String signatoryName;
    @ApiModelProperty("备注")
    private String remark;
cnas-process/src/main/java/com/ruoyi/process/service/ProcessReportService.java
@@ -20,7 +20,7 @@
 */
public interface ProcessReportService extends IService<ProcessReport> {
    IPage<ProcessReport> pageProcessReport(Page page, ProcessReport processReport);
    IPage<ProcessReportDto> pageProcessReport(Page page, ProcessReportDto processReport);
    void exportProcessReport(ProcessReportDto dto, HttpServletResponse response);
}
cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessReportServiceImpl.java
@@ -3,6 +3,7 @@
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
@@ -13,6 +14,7 @@
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SignatureImageUtil;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.process.dto.ProcessReportDto;
@@ -21,7 +23,6 @@
import com.ruoyi.process.service.ProcessReportService;
import com.ruoyi.system.mapper.UserMapper;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -53,20 +54,32 @@
    @Resource
    private ProcessReportMapper processReportMapper;
    @Value("${file.path}")
    private String imgUrl;
    @Resource
    private UserMapper userMapper;
    @Override
    public IPage<ProcessReport> pageProcessReport(Page page, ProcessReport processReport) {
        IPage<ProcessReport> processReportIPage = processReportMapper.pageProcessReport(page, QueryWrappers.queryWrappers(processReport));
    public IPage<ProcessReportDto> pageProcessReport(Page page, ProcessReportDto processReport) {
        IPage<ProcessReportDto> processReportIPage = processReportMapper.pageProcessReport(page, QueryWrappers.queryWrappers(processReport));
        return processReportIPage;
    }
    @Override
    public void exportProcessReport(ProcessReportDto dto, HttpServletResponse response) {
        List<ProcessReport> processReports = processReportMapper.exportProcessReport();
        List<ProcessReportDto> processReports = processReportMapper.exportProcessReport();
        for (ProcessReportDto processReport : processReports) {
            // å‘送人生成签名图片
            processReport.setSendUserRender(StringUtils.isNotBlank(processReport.getSendUserUrl())
                    ? Pictures.ofLocal(imgUrl + "/" + processReport.getSendUserUrl()).create() : null);
            // ç­¾æ”¶äººç”Ÿæˆå›¾ç‰‡
            processReport.setSignatoryRender(StringUtils.isNotBlank(processReport.getSignatory())
                    ? Pictures.ofStream(SignatureImageUtil.saveImageToFile(processReport.getSignatory())).create() : null);
        }
        // èŽ·å–è·¯å¾„
        InputStream inputStream = this.getClass().getResourceAsStream("/static/report-deal.docx");
        Configure configure = Configure.builder()
@@ -86,6 +99,7 @@
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java
@@ -751,11 +751,9 @@
        if (qualityMonitorDetailsId == null) {
            throw new ErrorException("缺少监控详情id");
        }
        QualityMonitorDetails qualityMonitorDetails = qualityMonitorDetailsService.getOne(Wrappers.<QualityMonitorDetails>lambdaUpdate()
                .eq(QualityMonitorDetails::getQualityMonitorDetailsId, qualityMonitorDetailsId));
        LocalDateTime now = LocalDateTime.now();
        Integer userId =SecurityUtils.getUserId().intValue();
        String contentType = file.getContentType();
        String urlString;
        String pathName;
        try {
@@ -768,10 +766,13 @@
            urlString = realpath + "/" + pathName;
            file.transferTo(new File(urlString));
            wordInsertUrl(new HashMap<String, Object>() {{
                put("writeUrl", UserUtils.getFinalUserSignatureUrl(userId));
                put("writeDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(now)).create());
            }}, wordUrl + "/" + pathName.replace("/word", wordUrl));
            // åˆ¤æ–­æ˜¯å¦æ˜¯pdf
            if (!contentType.contains("pdf")) {
                wordInsertUrl(new HashMap<String, Object>() {{
                    put("writeUrl", UserUtils.getFinalUserSignatureUrl(userId));
                    put("writeDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(now)).create());
                }}, wordUrl + "/" + pathName.replace("/word", wordUrl));
            }
            qualityMonitorDetailsService.update(Wrappers.<QualityMonitorDetails>lambdaUpdate()
                    .eq(QualityMonitorDetails::getQualityMonitorDetailsId, qualityMonitorDetailsId)
@@ -807,7 +808,7 @@
        // æ·»åŠ æ‰¹å‡†äºº
        QualityMonitorDetails details = qualityMonitorDetailsMapper.selectById(qualityMonitorDetails.getQualityMonitorDetailsId());
        if (StringUtils.isNotBlank(details.getFinishReportUrl())) {
        if (StringUtils.isNotBlank(details.getFinishReportUrl()) && !details.getFinishReportUrl().contains(".pdf")) {
            wordInsertUrl(new HashMap<String, Object>() {{
                put("ratifyUrl", UserUtils.getFinalUserSignatureUrl(userId));
                put("ratifyDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(now)).create());
cnas-process/src/main/resources/mapper/ProcessReportMapper.xml
@@ -18,7 +18,7 @@
        <result column="update_user" property="updateUser"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <select id="pageProcessReport" resultType="com.ruoyi.process.pojo.ProcessReport">
    <select id="pageProcessReport" resultType="com.ruoyi.process.dto.ProcessReportDto">
        select * from (select cpr.* ,
        u1.name sendUserName
        from cnas_process_report cpr
@@ -27,10 +27,10 @@
            ${ew.customSqlSegment}
        </if>
    </select>
    <select id="exportProcessReport" resultType="com.ruoyi.process.pojo.ProcessReport">
    <select id="exportProcessReport" resultType="com.ruoyi.process.dto.ProcessReportDto">
        select ROW_NUMBER() OVER (ORDER BY cpr.id) AS indexs,
        cpr.* ,
        u1.name sendUserName
        u1.signature_url sendUserUrl
        from cnas_process_report cpr
        left join user u1 on send_user=u1.id
    </select>
cnas-process/src/main/resources/static/report-deal.docx
Binary files differ
ruoyi-common/src/main/java/com/ruoyi/common/utils/SignatureImageUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.ruoyi.common.utils;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
/**
 * @Author zhuo
 * @Date 2025/5/7
 */
public class SignatureImageUtil {
    /**
     * æ ¹æ®ä¸­æ–‡å¯¼å‡ºç­¾åå›¾ç‰‡
     * @param text
     * @return
     * @throws IOException
     * @throws FontFormatException
     */
    public static InputStream saveImageToFile(String text){
        // èŽ·å–å­—ä½“åº“
        Font font = null;
        try (InputStream is = new ClassPathResource("/ttf/signature.ttf").getInputStream()) {
            font = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(50f);
        } catch (FontFormatException | IOException e) {
            throw new RuntimeException(e);
        }
        int width = 100; // å›¾ç‰‡çš„宽度
        int height = 50; // å›¾ç‰‡çš„高度
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setFont(font);
        // è®¾ç½®æ–‡å­—颜色为黑色
        g2d.setColor(Color.black);
        // è®¾ç½®æ–‡å­—在图片中的位置
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(text, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = -bounds.getY();
        double baseY = y + ascent;
        g2d.drawString(text, (int) x, (int) baseY);
        g2d.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return new ByteArrayInputStream(os.toByteArray());
    }
}
ruoyi-common/src/main/resources/ttf/signature.ttf
Binary files differ