时间:4月15日-4月26

一、本期前言

大家好,这是我们“智愈”医疗自助服务系统的第三篇开发博客。在前两期中,我们完成了系统基础架构搭建、智能医生对话模块和疾病药品查询功能。本期我将重点介绍病情诊断书导入分析功能模块的完整完善开发过程,包括通义千问VL大模型集成、AI智能识别、诊断报告生成等核心功能。

 二、功能概述

2.1 业务需求

在医疗场景中,用户经常需要上传诊断书、检验报告等医疗文档,希望系统能够:
- 自动识别文档中的关键医疗信息
- 提取患者基本信息、诊断结论、用药建议等
- 将非结构化的医疗文档转化为结构化数据
- 生成美观的诊断分析报告(支持导出PDF)

2.2 功能模块

 模块名称 | 核心功能 
 诊断书上传模块 | 支持图片上传、拖拽上传、文件预览 
 AI识别模块 | 通义千问VL大模型智能识别医疗文档 
 结构化展示模块 | 分模块展示患者信息、诊断、检查、用药等 
 报告生成模块 | 一键生成专业诊断报告,支持PDF导出 

2.3 技术架构

三、技术选型

| 技术组件 | 版本 | 用途 |
| Spring Boot | 2.6.7 | 后端框架 |
| 通义千问VL | qwen-vl-plus | 多模态视觉语言模型 |
| 阿里云OSS | 2.4.0 | 图片存储 |
| OkHttp | 4.10.0 | HTTP客户端 |
| FastJSON | 1.2.47 | JSON解析 |
| Thymeleaf | - | 前端模板引擎 |

通义千问VL是阿里云推出的多模态大模型,具备强大的OCR能力和语义理解能力。相比传统“OCR + NLP解析”的两步走方案,VL模型可以直接端到端输出结构化结果,开发效率更高,识别效果更好。

 四、核心功能实现

4.1 AI识别服务 - MedicalRecordAnalysisService这是整个功能的核心,负责调用通义千问VL大模型分析诊断书图片。
 

@Slf4j
@Service
public class MedicalRecordAnalysisService {

    @Value("${ai-key}")
    private String apiKey;

    private static final String DASHSCOPE_API_URL = 
        "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation";

    /**
     * 使用Base64方式分析诊断书(推荐,不依赖OSS公网访问)
     */
    public JSONObject uploadAndAnalyzeWithBase64(MultipartFile file) throws IOException {
        // 1. 验证文件类型
        validateFileType(file);
        
        // 2. 将文件转为Base64
        byte[] bytes = file.getBytes();
        String base64Content = java.util.Base64.getEncoder().encodeToString(bytes);
        String dataUrl = "data:" + file.getContentType() + ";base64," + base64Content;
        
        // 3. 调用通义千问VL分析
        return analyzeMedicalRecordWithBase64(dataUrl);
    }
}

4.2 Prompt工程设计

Prompt是影响AI识别效果的关键因素。经过多轮优化,我设计了以下专业医疗Prompt:

private String buildMedicalPrompt() {
    return "你是一位专业的医疗文档分析专家。请分析这张图片。\n\n" +
           "第一步:判断这张图片是否是医疗相关的文档(诊断书、检验报告、处方、出院小结、病历等)。\n\n" +
           "如果不是医疗文档,请返回:\n" +
           "{\n" +
           "  \"is_medical_document\": false,\n" +
           "  \"message\": \"请上传诊断书、检验报告等医疗文档\",\n" +
           "  \"detected_content_type\": \"识别到的文件类型\"\n" +
           "}\n\n" +
           "如果是医疗文档,请提取以下信息并以JSON格式返回:\n" +
           "{\n" +
           "  \"is_medical_document\": true,\n" +
           "  \"patient_name\": \"患者姓名\",\n" +
           "  \"patient_age\": \"年龄\",\n" +
           "  \"patient_gender\": \"性别\",\n" +
           "  \"diagnosis\": {\n" +
           "    \"primary_diagnosis\": \"主要诊断结论\",\n" +
           "    \"secondary_diagnosis\": \"次要诊断\",\n" +
           "    \"icd_code\": \"疾病编码\"\n" +
           "  },\n" +
           "  \"symptoms\": [\"症状1\", \"症状2\"],\n" +
           "  \"examinations\": [\n" +
           "    {\n" +
           "      \"item\": \"检查项目\",\n" +
           "      \"result\": \"结果\",\n" +
           "      \"reference\": \"参考范围\",\n" +
           "      \"status\": \"正常/偏高/偏低\"\n" +
           "    }\n" +
           "  ],\n" +
           "  \"medications\": [\n" +
           "    {\n" +
           "      \"name\": \"药品名称\",\n" +
           "      \"dosage\": \"用法用量\",\n" +
           "      \"frequency\": \"频率\",\n" +
           "      \"duration\": \"周期\"\n" +
           "    }\n" +
           "  ],\n" +
           "  \"recommendations\": \"医生建议\",\n" +
           "  \"report_date\": \"报告日期\",\n" +
           "  \"hospital_name\": \"医院名称\",\n" +
           "  \"doctor_name\": \"医生姓名\"\n" +
           "}\n\n" +
           "要求:只输出JSON,不要有其他文字。";
}

4.3 前端页面 - 智能扫描界面

设计了美观实用的前端页面,支持:
- 点击/拖拽上传
- 图片预览
- AI分析进度提示
- 结构化结果展示

核心JavaScript功能:

// 开始分析
function startAnalysis() {
    const formData = new FormData();
    formData.append('file', currentFile);
    
    $.ajax({
        url: '/api/medical-record/analyze',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function(response) {
            currentAnalysisData = response.data;
            displayAnalysisResult(currentAnalysisData);
            layer.msg('分析完成!', {icon: 1});
        }
    });
}

// 生成诊断报告
function generateReportHTML(analysisData) {
    // 动态生成美观的HTML报告
    // 包含患者信息、诊断结论、检验检查、用药建议等
}

4.4 PDF报告生成(浏览器原生方案)

不同于传统的后端PDF生成方案,我采用了浏览器打印转PDF的方式,优势明显:

| 对比项 | 后端生成PDF | 浏览器打印方案 |
| 中文支持 | 需要配置字体,容易乱码 | ✅ 完美支持 |
| 样式控制 | 代码复杂,调试困难 | ✅ CSS完全控制 |
| 开发成本 | 高(需学习PDF库) | ✅ 低(HTML+CSS) |
| 维护成本 | 高 | ✅ 低 |
| 服务器压力 | 有 | ✅ 无 |实现代码:

// 预览报告
function previewReport() {
    const reportHtml = generateReportHTML(currentAnalysisData);
    document.getElementById('reportContent').innerHTML = reportHtml;
    document.getElementById('reportPreviewModal').style.display = 'block';
}

// 打印/保存PDF
function printReport() {
    const printWindow = window.open('', '_blank');
    printWindow.document.write(reportContent);
    printWindow.print();  // 用户可选择"另存为PDF"
}

 五、遇到的主要问题及解决方案

 问题1:AI无法下载OSS图片内容

错误信息: `Failed to download multimodal content`

原因分析: OSS Bucket默认私有,通义千问VL无法直接访问

解决方案: 采用Base64方式,将图片直接编码后传给AI模型

// 将图片转为Base64
byte[] bytes = file.getBytes();
String base64Content = Base64.getEncoder().encodeToString(bytes);
String dataUrl = "data:" + contentType + ";base64," + base64Content;


 

问题2:MessageManager在新版SDK中不存在

错误信息: `Cannot resolve symbol 'MessageManager'`

原因分析: DashScope SDK 2.x版本移除了MessageManager

解决方案: 改用List<Message>方式构建消息

// 旧版(2.9.0)
MessageManager msgManager = new MessageManager(10);

// 新版(2.16.7)
List<Message> messages = Arrays.asList(
    Message.builder().role(Role.SYSTEM.getValue()).content("...").build(),
    Message.builder().role(Role.USER.getValue()).content("...").build()
);

 问题3:非医疗文档误识别

问题描述: 用户上传录取通知书等非医疗文档,AI仍尝试提取医疗信息

解决方案: 在Prompt中增加文档类型判断逻辑,返回明确提示
{
  "is_medical_document": false,
  "message": "请上传诊断书、检验报告等医疗文档",
  "detected_content_type": "录取通知书"
}
 

问题4:PDF生成中文乱码

问题描述: iTextPDF生成的中文PDF出现乱码

解决方案: 放弃后端生成方案,改用浏览器打印转PDF,完美解决中文问题

 六、最终效果展示

6.1 上传分析界面

页面支持点击或拖拽上传诊断书图片,上传后显示预览,点击"开始AI分析"即可调用通义千问VL大模型进行智能识别。

6.2 分析结果展示

分析完成后,系统会结构化展示:
- 患者基本信息
- 诊断结论
- 症状表现
- 检验检查项目(含异常标记)
- 用药建议
- 医生建议

 6.3 诊断报告预览以及导出pdf

点击"生成诊断报告"按钮,弹出专业美观的诊断报告预览窗口,包含:
- 医院标识和报告编号
- 患者信息和报告日期
- 诊断结论(突出显示)
- 检验检查表格
- 用药建议表格
- 诊断医师信息和置信度
- 免责声明点击"打印/保存为PDF",调用浏览器打印功能,用户可选择"另存为PDF",生成的PDF格式与预览完全一致。

 七、项目代码结构
src/main/java/world/example/
├── controller/
│   └── MedicalScanController.java      # 智能扫描控制器
├── service/
│   └── MedicalRecordAnalysisService.java # AI分析服务
├── component/
│   └── OssClient.java                   # OSS上传组件
└── utils/
    └── PdfExportUtil.java               # PDF工具类(备用)

src/main/resources/templates/
├── common/
│   └── common-bar.html                  # 公共导航(已添加菜单)
└── medical-scan.html                    # 智能扫描页面
 

八、开发测试数据

| 测试项 | 测试内容 | 识别效果 |
| 印刷体诊断书 | 标准医院打印的诊断书 | ✅ 准确率约95% |
| 检验报告 | 血常规、生化检验单 | ✅ 表格数据提取准确 |
| PDF文档 | 多页医疗报告 | ✅ 支持识别 |
| 非医疗文档 | 录取通知书等 | ✅ 正确识别并提示 |

九、后续优化计划

1. 提升识别准确率:收集更多医疗文档样本,持续优化Prompt
2. 历史记录功能:保存用户的分析历史,方便查看
3. 医生审核功能:AI生成报告后,支持医生在线审核修改
4. 多语言支持:支持英文、日文等医疗文档识别

十、总结

本期开发完成了智能诊断书扫描功能的完整实现,包括:

1. ✅ 集成通义千问VL大模型,实现医疗文档智能识别
2. ✅ 设计专业Prompt,提升识别准确率和用户体验
3. ✅ 实现Base64传图方案,解决OSS私有访问问题
4. ✅ 开发结构化结果展示页面
5. ✅ 实现美观的诊断报告生成和PDF导出

通过本次开发,我深入掌握了:
- 多模态大模型(VL)的调用与Prompt工程
- SpringBoot + AI的实战集成
- 浏览器打印转PDF的前端方案
- 医疗文档OCR的特殊处理技巧

本期内容就到这里,下期我将介绍系统的其他功能模块开发

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐