3 Commits ab3fedf46f ... 78c0f216cd

Autore SHA1 Messaggio Data
  zhangqin 78c0f216cd coding:审方 1 settimana fa
  zhangqin 7d1f3b0374 coding:审方 1 settimana fa
  zhangqin 40b534f760 coding:审方 1 settimana fa

+ 0 - 121
fs-common/src/main/java/com/fs/common/utils/ThumbnailatorWatermark.java

@@ -1,121 +0,0 @@
-package com.fs.common.utils;
-
-import net.coobird.thumbnailator.Thumbnails;
-import net.coobird.thumbnailator.geometry.Positions;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-
-public class ThumbnailatorWatermark {
-
-    /**
-     * 对处方图片添加水印并返回字节数组
-     *
-     * @param imageUrl           处方图片的URL
-     * @param watermarkImageUrl 本地水印图片路径
-     * @return 添加水印后的图片字节数组
-     * @throws IOException
-     */
-    public static byte[] addWatermarkToNetworkImage(String imageUrl, String watermarkImageUrl,String doctorName) throws IOException {
-        try {
-            // 读取原图片
-            URL url = new URL(imageUrl);
-            InputStream inputStream = url.openStream();
-
-            // 读取水印图片
-            URL watermarkURL = new URL(watermarkImageUrl);
-            InputStream watermarkInputStream = watermarkURL.openStream();
-            BufferedImage watermarkImage = ImageIO.read(watermarkInputStream);
-            // 缩放水印
-            // 2. 计算并缩放水印图尺寸 (例如:缩放到原图宽度的1/8)
-            int newWatermarkWidth = watermarkImage.getWidth() / 8;
-            // 按水印图原比例计算高度
-            int newWatermarkHeight = (int) ((double) newWatermarkWidth / watermarkImage.getWidth() * watermarkImage.getHeight());
-            BufferedImage scaledWatermark = Thumbnails.of(watermarkImage)
-                    .size(newWatermarkWidth, newWatermarkHeight)
-                    .asBufferedImage();
-
-            // 创建签名图片
-            BufferedImage signatureImage = createTextImageWithBorder(doctorName, Color.RED, 36,2);
-
-            // 使用Thumbnailator处理并输出到字节数组
-            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-            Thumbnails.of(inputStream)
-                    .scale(1)
-                    .watermark(Positions.TOP_RIGHT, scaledWatermark, 0.5f)
-                    .watermark(
-                            new AbsolutePosition(860, 1340), // 使用自定义坐标位置
-                            signatureImage,
-                            0.7f // 透明度
-                    )
-                    .outputQuality(0.9)
-                    .outputFormat("jpg")
-                    .toOutputStream(outputStream);
-
-            inputStream.close();
-            return outputStream.toByteArray();
-        } catch (Exception e) {
-            System.err.println("添加水印失败: " + e.getMessage());
-            e.printStackTrace();
-            throw e;
-        }
-    }
-
-    private static BufferedImage createTextImageWithBorder(String text, Color color, int fontSize, int borderWidth) {
-        // 创建临时Graphics以计算文字尺寸
-        BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D g = tempImage.createGraphics();
-        Font font = new Font("微软雅黑", Font.PLAIN, fontSize);
-        g.setFont(font);
-        FontMetrics metrics = g.getFontMetrics();
-
-        // 计算文字宽度和高度
-        int textWidth = metrics.stringWidth(text);
-        int textHeight = metrics.getHeight();
-        g.dispose();
-
-        // 添加边框和内边距
-        int padding = 5; // 文字与边框之间的内边距
-        int totalWidth = textWidth + 2 * (borderWidth + padding);
-        int totalHeight = textHeight + 2 * (borderWidth + padding);
-
-        // 创建正式的文字图片 - 使用透明背景
-        BufferedImage textImage = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D g2d = textImage.createGraphics();
-
-        // 设置抗锯齿
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-
-        // 绘制圆角矩形边框
-        g2d.setColor(color);
-        g2d.setStroke(new BasicStroke(borderWidth)); // 设置边框粗细
-        g2d.drawRoundRect(
-                borderWidth/2,
-                borderWidth/2,
-                totalWidth - borderWidth,
-                totalHeight - borderWidth,
-                10, 10 // 圆角半径
-        );
-
-        // 设置字体和颜色
-        g2d.setFont(font);
-        g2d.setColor(color);
-
-        // 绘制文字 - 位置居中
-        int textX = (totalWidth - textWidth) / 2;
-        int textY = (totalHeight - textHeight) / 2 + metrics.getAscent();
-        g2d.drawString(text, textX, textY);
-
-        g2d.dispose();
-        return textImage;
-    }
-
-}

+ 9 - 9
fs-service/src/main/java/com/fs/his/service/impl/FsPrescribeServiceImpl.java

@@ -1,7 +1,6 @@
 package com.fs.his.service.impl;
 
 import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -10,7 +9,9 @@ import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.ThumbnailatorWatermark;
+import com.fs.hisStore.domain.FsStoreOrderScrm;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
+import com.fs.hospital580.util.ThumbnailatorWatermark;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
@@ -90,6 +91,9 @@ public class FsPrescribeServiceImpl implements IFsPrescribeService
     @Autowired
     FsExportTaskMapper fsExportTaskMapper;
 
+    @Autowired
+    ThumbnailatorWatermark thumbnailatorWatermark;
+
     @Autowired
     private Hospital580PrescriptionScrmService orderScrmService;
 
@@ -98,6 +102,7 @@ public class FsPrescribeServiceImpl implements IFsPrescribeService
 
     @Autowired
     private IFsStoreProductScrmService productScrmService;
+
     /**
      * 查询处方
      *
@@ -826,13 +831,8 @@ public class FsPrescribeServiceImpl implements IFsPrescribeService
         prescribe.setAuditApothecaryName(doctor.getDoctorName());
         prescribe.setAuditApothecaryId(doctor.getDoctorId());
         prescribe.setReason(param.getAuditReason());
-        try {
-            // 处方添加水印
-            CloudStorageService storage = OSSFactory.build();
-            String url = storage.uploadSuffix(ThumbnailatorWatermark.addWatermarkToNetworkImage(prescribe.getDstFilePath(),configService.selectConfigByKey("his.prescription.url"),doctor.getSignUrl()), ".jpg");
-            prescribe.setDstFilePath(url);
-        } catch (IOException e) {
-        }
+        // 添加审核水印
+        prescribe.setDstFilePath(thumbnailatorWatermark.addWatermarkToNetworkImage(param.getPrescribeId(),1,prescribe.getDstFilePath()));
         prescribe.updateById();
         if(param.getStatus().equals(1)){
             //发送信息

+ 123 - 0
fs-service/src/main/java/com/fs/hospital580/util/ThumbnailatorWatermark.java

@@ -0,0 +1,123 @@
+package com.fs.hospital580.util;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.AbsolutePosition;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
+import com.fs.system.service.ISysConfigService;
+import net.coobird.thumbnailator.Thumbnails;
+import net.coobird.thumbnailator.geometry.Positions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class ThumbnailatorWatermark {
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private ISysConfigService configService;
+
+
+    public String addWatermarkToNetworkImage(Long preId, Integer orderStatus, String signUrl) {
+        try {
+            // 处方原图
+            String imageUrl = redisCache.getCacheObject("prescription:dstFilePath:" + preId);
+            if (ObjectUtil.isEmpty(imageUrl)) {
+                return null;
+            }
+            // 水印图片
+            String watermarkURLJson = configService.selectConfigByKey("his.prescription.url");
+            JSONObject jsonObject = JSONUtil.parseObj(watermarkURLJson);
+
+            // 读取原图片
+            URL url = new URL(imageUrl);
+            InputStream inputStream = url.openStream();
+            String watermarkImageUrl = "";
+            switch (orderStatus) {
+                // 代付款
+                case 1:
+                    watermarkImageUrl = jsonObject.getStr("start");
+                    break;
+                // 退款
+                case 3:
+                    watermarkImageUrl = jsonObject.getStr("end");
+                    break;
+                // 已支付
+                default:
+                    watermarkImageUrl = jsonObject.getStr("ing");
+                    break;
+            }
+            // 读取水印图片
+            URL watermarkURL = new URL(watermarkImageUrl);
+            InputStream watermarkInputStream = watermarkURL.openStream();
+            BufferedImage watermarkImage = ImageIO.read(watermarkInputStream);
+            // 缩放水印
+            // 2. 计算并缩放水印图尺寸 (例如:缩放到原图宽度的1/8)
+            int newWatermarkWidth = watermarkImage.getWidth() / 8;
+            // 按水印图原比例计算高度
+            int newWatermarkHeight = (int) ((double) newWatermarkWidth / watermarkImage.getWidth() * watermarkImage.getHeight());
+            BufferedImage scaledWatermark = Thumbnails.of(watermarkImage)
+                    .size(newWatermarkWidth, newWatermarkHeight)
+                    .asBufferedImage();
+
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            if (ObjectUtil.isNotEmpty(signUrl)) {
+                // 创建签名图片
+                URL watermarkURL2 = new URL(signUrl);
+                InputStream watermarkInputStream2 = watermarkURL2.openStream();
+                BufferedImage signatureImage = ImageIO.read(watermarkInputStream2);
+                // 缩放水印
+                // 2. 计算并缩放水印图尺寸 (例如:缩放到原图宽度的1/4)
+                int newWatermarkWidth2 = signatureImage.getWidth() / 8;
+                // 按水印图原比例计算高度
+                int newWatermarkHeight2 = (int) ((double) newWatermarkWidth2 / signatureImage.getWidth() * signatureImage.getHeight());
+                BufferedImage scaledWatermark2 = Thumbnails.of(signatureImage)
+                        .size(newWatermarkWidth2, newWatermarkHeight2)
+                        .asBufferedImage();
+
+                // 使用Thumbnailator处理并输出到字节数组
+                Thumbnails.of(inputStream)
+                        .scale(1)
+                        .watermark(Positions.TOP_RIGHT, scaledWatermark, 0.5f)
+                        .watermark(
+                                new AbsolutePosition(800, 1300), // 使用自定义坐标位置
+                                scaledWatermark2,
+                                1f // 透明度
+                        )
+                        .outputQuality(0.9)
+                        .outputFormat("jpg")
+                        .toOutputStream(outputStream);
+            } else {
+                Thumbnails.of(inputStream)
+                        .scale(1)
+                        .watermark(Positions.TOP_RIGHT, scaledWatermark, 0.5f)
+                        .outputQuality(0.9)
+                        .outputFormat("jpg")
+                        .toOutputStream(outputStream);
+            }
+
+
+            inputStream.close();
+            // 处方图片阶段
+            redisCache.setCacheObject("prescription:dstFilePath:phase" + preId, orderStatus, 2, TimeUnit.DAYS);
+            CloudStorageService storage = OSSFactory.build();
+            return storage.uploadSuffix(outputStream.toByteArray(), ".jpg");
+        } catch (Exception e) {
+            System.err.println("添加水印失败: " + e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+}

+ 32 - 1
fs-user-app/src/main/java/com/fs/app/facade/impl/Hospital580FacadeServiceImpl.java

@@ -14,6 +14,7 @@ import com.fs.app.exception.FSException;
 import com.fs.app.facade.Hospital580FacadeService;
 import com.fs.common.core.domain.PageResponse;
 import com.fs.common.core.domain.Result;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.framework.aspectj.lock.DistributeLock;
 import com.fs.his.domain.FsDoctor;
 import com.fs.his.domain.FsPatient;
@@ -30,6 +31,7 @@ import com.fs.hospital580.service.Hospital580PrescriptionAnswerScrmService;
 import com.fs.hospital580.service.Hospital580PrescriptionMedicineScrmService;
 import com.fs.hospital580.service.Hospital580PrescriptionScrmService;
 import com.fs.hospital580.service.Hospital580Service;
+import com.fs.hospital580.util.ThumbnailatorWatermark;
 import com.fs.hospital580.vo.MedicineSyncVo;
 import com.fs.hospital580.vo.PrescriptionMedicineScrmVo;
 import com.fs.hospital580.vo.RefusePrescriptionVo;
@@ -52,6 +54,7 @@ import java.time.ZoneId;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @Service
@@ -78,6 +81,11 @@ public class Hospital580FacadeServiceImpl implements Hospital580FacadeService {
     @Autowired
     private IFsDoctorService doctorService;
 
+    @Autowired
+    private RedisCache redisCache;
+    @Autowired
+    private ThumbnailatorWatermark thumbnailatorWatermark;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     @DistributeLock(key = "#vo.userId", scene = "savePreDemand", waitTime = 5000, errorMsg = "新增问诊信息失败")
@@ -152,10 +160,14 @@ public class Hospital580FacadeServiceImpl implements Hospital580FacadeService {
         FsStoreOrderScrm fsStoreOrderScrm = orderService.selectFsStoreOrderById(prescription.getStoreOrderId());
         // 查询药剂师
         FsDoctor fsDoctor = doctorService.findByStoreId(fsStoreOrderScrm.getStoreId());
-        if (ObjectUtil.isNotEmpty(fsDoctor)){
+        if (ObjectUtil.isNotEmpty(fsDoctor)) {
             prescription.setAuditApothecaryName(fsDoctor.getDoctorName());
             prescription.setAuditApothecaryId(fsDoctor.getDoctorId());
         }
+        // 处方图片
+        redisCache.setCacheObject("prescription:dstFilePath:" + prescription.getPreId(), vo.getDstFilePath(), 2, TimeUnit.DAYS);
+        // 处方添加待生效水印
+        prescription.setDstFilePath(thumbnailatorWatermark.addWatermarkToNetworkImage(prescription.getPreId(), fsStoreOrderScrm.getStatus(), null));
 
         // 更新处方记录
         prescription.updateById();
@@ -280,6 +292,25 @@ public class Hospital580FacadeServiceImpl implements Hospital580FacadeService {
     @Override
     public Result<PrescriptionDetailRes> prescriptionDetail(String userId, Long preId) {
         Hospital580PrescriptionScrmEntity byId = orderScrmService.getById(preId);
+        // 判断处方阶段和订单阶段是否相同
+        Integer str = redisCache.getCacheObject("prescription:dstFilePath:phase" + preId);
+        if (ObjectUtil.isNotEmpty(str) && 3 == str) {
+            FsStoreOrderScrm fsStoreOrderScrm = orderService.selectFsStoreOrderById(byId.getStoreOrderId());
+            String singUrl = null;
+            if (byId.getAuditStatus() > 1) {
+                FsDoctor fsDoctor = doctorService.selectFsDoctorByDoctorId(byId.getAuditApothecaryId());
+                singUrl = fsDoctor.getSignUrl();
+            }
+            if (fsStoreOrderScrm.getStatus().equals(-3)) {
+                // 订单已取消 设置为已失效
+                thumbnailatorWatermark.addWatermarkToNetworkImage(preId, 3, singUrl);
+            } else if (fsStoreOrderScrm.getStatus() > 0) {
+                // 订单已付款 设置为已生效
+                thumbnailatorWatermark.addWatermarkToNetworkImage(preId, 2, singUrl);
+            }
+        }
+
+
         PrescriptionDetailRes prescriptionScrmVo = BeanUtil.toBean(byId, PrescriptionDetailRes.class);
         prescriptionScrmVo.setDrugRspList(medicineScrmService.list(new LambdaQueryWrapper<Hospital580PrescriptionMedicineScrmEntity>()
                         .eq(Hospital580PrescriptionMedicineScrmEntity::getPreId, prescriptionScrmVo.getPreId()))