| 
					
				 | 
			
			
				@@ -244,8 +244,9 @@ public class PrescriptionImageServiceImpl implements PrescriptionImageService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 绘制药品列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return 返回最后一行的Y坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 绘制药品列表(每药两行:第一行药名规格数量,第二行用法用量) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 药品内部两行之间无空行,每个药品(包括最后一个)之后都加一个空白行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 返回最后一行的Y坐标(即最后一个空白行之后的位置) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public int drawDrugList(Graphics2D pen, List<FsPrescribeDrug> drugs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (drugs == null || drugs.isEmpty()) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -253,48 +254,149 @@ public class PrescriptionImageServiceImpl implements PrescriptionImageService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         int x = 133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int y = 728; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int lineHeight = 30; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int y = 680; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (FsPrescribeDrug drug : drugs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 格式: 药品名 规格 用法 频次 每次用量 x 数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            StringBuilder sb = new StringBuilder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 行高设置(可根据实际字体微调) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int innerLineSpacing = 40;  // 药品内部两行之间的间距(含呼吸感,避免粘连) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int blankLine = 40;         // 药品之间的空白行(比内部稍大,形成视觉分组) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (FsPrescribeDrug drug : drugs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // ========== 第一行:药名 + 规格 + 数量 ========== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            StringBuilder line1 = new StringBuilder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (StringUtils.isNotBlank(drug.getDrugName())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getDrugName()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line1.append(drug.getDrugName()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (StringUtils.isNotBlank(drug.getDrugSpec())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getDrugSpec()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drug.getUsageMethod())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getUsageMethod()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line1.append(" ").append(drug.getDrugSpec()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drug.getUsageFrequencyUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getUsageFrequencyUnit()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (drug.getDrugNum() != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line1.append("x").append(drug.getDrugNum()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (StringUtils.isNotBlank(drug.getDrugUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    line1.append(drug.getDrugUnit()).append("。"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drug.getUsagePerUseCount())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getUsagePerUseCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String firstLine = line1.toString().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.isNotBlank(firstLine)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                y = drawDrugTextLine(pen, firstLine, x, y, 1000, innerLineSpacing); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drug.getUsagePerUseUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getUsagePerUseUnit()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y += innerLineSpacing; // 第一行占位(即使无内容也占) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // ========== 第二行:用法用量 ========== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            StringBuilder line2 = new StringBuilder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.isNotBlank(drug.getUsageMethod())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line2.append("用法用量:").append(drug.getUsageMethod()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (drug.getDrugNum() != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append("x ").append(drug.getDrugNum()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.isNotBlank(drug.getUsagePerUseCount())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line2.append(",").append(drug.getUsagePerUseCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (StringUtils.isNotBlank(drug.getUsagePerUseUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    line2.append(drug.getUsagePerUseUnit()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drug.getDrugUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                sb.append(drug.getDrugUnit()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.isNotBlank(drug.getUsageFrequencyUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                line2.append(",").append(drug.getUsageFrequencyUnit()).append("。"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            String drugInfo = sb.toString().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (StringUtils.isNotBlank(drugInfo)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                y = drawMultiLineText(pen, drugInfo, x, y, 1000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                y += lineHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String secondLine = line2.toString().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.isNotBlank(secondLine)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                y = drawDrugTextLine(pen, secondLine, x, y, 1000, innerLineSpacing); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y += innerLineSpacing; // 第二行占位(即使无内容也占) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // ========== 每个药品之后(包括最后一个)加一个空白行 ========== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y += blankLine; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 专用于药品列表的文本绘制:支持自动换行,返回最后一行文本的基线 Y 坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 不额外增加行高,由调用方控制换行(如 y += innerLineSpacing) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private int drawDrugTextLine(Graphics2D pen, String text, int x, int y, int maxWidth, int lineHeight) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (StringUtils.isBlank(text)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FontMetrics fm = pen.getFontMetrics(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        StringBuilder currentLine = new StringBuilder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int currentY = y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (char c : text.toCharArray()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String testLine = currentLine.toString() + c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int testWidth = fm.stringWidth(testLine); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果加上当前字符会超宽,且当前行已有内容,则换行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (testWidth > maxWidth && currentLine.length() > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pen.drawString(currentLine.toString(), x, currentY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                currentY += lineHeight; // 使用固定 lineHeight 换行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                currentLine = new StringBuilder().append(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                currentLine.append(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 绘制最后一行(不额外增加 lineHeight) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (currentLine.length() > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pen.drawString(currentLine.toString(), x, currentY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return currentY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//     * 绘制药品列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//     * @return 返回最后一行的Y坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    public int drawDrugList(Graphics2D pen, List<FsPrescribeDrug> drugs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        if (drugs == null || drugs.isEmpty()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            return 330; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        int x = 133; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        int y = 728; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        int lineHeight = 30; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        for (FsPrescribeDrug drug : drugs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            // 格式: 药品名 规格 用法 频次 每次用量 x 数量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            StringBuilder sb = new StringBuilder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getDrugName())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getDrugName()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getDrugSpec())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getDrugSpec()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getUsageMethod())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getUsageMethod()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getUsageFrequencyUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getUsageFrequencyUnit()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getUsagePerUseCount())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getUsagePerUseCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getUsagePerUseUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getUsagePerUseUnit()).append(" "); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (drug.getDrugNum() != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append("x ").append(drug.getDrugNum()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drug.getDrugUnit())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                sb.append(drug.getDrugUnit()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            String drugInfo = sb.toString().trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            if (StringUtils.isNotBlank(drugInfo)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                y = drawMultiLineText(pen, drugInfo, x, y, 760); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//                y += lineHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        return y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * 绘制医嘱 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -329,7 +431,7 @@ public class PrescriptionImageServiceImpl implements PrescriptionImageService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 药师签名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (StringUtils.isNotBlank(param.getDrugDoctorUrl())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                BufferedImage pharmacistSign = downloadSignatureImage("https://ysy-1329817240.cos.ap-guangzhou.myqcloud.com/ysy/20251021/be7ef2dda6d94b6c97c9b41bdb3a9cb8.png"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BufferedImage pharmacistSign = downloadSignatureImage("https://ysy-1329817240.cos.ap-guangzhou.myqcloud.com/ysy/20251028/ed509381390049c9ad2a17e95d8b8732.png"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (pharmacistSign != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     Image scaledSign = pharmacistSign.getScaledInstance(120, 80, Image.SCALE_SMOOTH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     pen.drawImage(scaledSign, 1076, 1528, null); 
			 |