# 捐款证书中文乱码修复指南 ## 问题描述 生成的捐款证书图片中,中文字符显示为乱码或方块,影响证书的正常使用。 问题示例:https://file-s209.shoplnk.cn/poster/10547/pay/2536.jpg?v=0409 ## 根本原因 1. **系统缺少中文字体**:Docker容器(Alpine Linux)默认不包含中文字体 2. **字体回退机制不完善**:当找不到中文字体时,回退到的默认字体不支持中文 3. **字体检测不够严格**:原代码只检测单个汉字,可能导致误判 ## 修复方案 ### 方案一:重新构建Docker镜像(推荐) #### 1. 使用更新后的Dockerfile 项目的 `Dockerfile` 已经更新,新增了中文字体支持: ```dockerfile # 安装必要工具和中文字体支持 RUN apk add --no-cache wget fontconfig ttf-dejavu && \ # 下载并安装文泉驿微米黑字体(更好的中文支持) wget -O /tmp/wqy-microhei.ttc https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc && \ mkdir -p /usr/share/fonts/truetype/wqy && \ mv /tmp/wqy-microhei.ttc /usr/share/fonts/truetype/wqy/ && \ # 刷新字体缓存 fc-cache -fv ``` #### 2. 重新构建镜像 ```bash # 打包项目 mvn clean package -DskipTests # 构建Docker镜像 docker build -t websoft-api:latest . # 停止旧容器 docker stop websoft-api-container # 删除旧容器 docker rm websoft-api-container # 启动新容器 docker run -d \ --name websoft-api-container \ -p 9200:9200 \ -v /path/to/uploads:/app/uploads \ -v /path/to/logs:/app/logs \ -e SPRING_PROFILES_ACTIVE=prod \ websoft-api:latest ``` ### 方案二:在运行中的容器内安装字体 如果不方便重新构建镜像,可以在运行中的容器内安装字体: ```bash # 进入容器 docker exec -it -u root websoft-api-container sh # 安装字体工具 apk add --no-cache fontconfig ttf-dejavu # 下载中文字体 wget -O /tmp/wqy-microhei.ttc https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc # 创建字体目录 mkdir -p /usr/share/fonts/truetype/wqy # 移动字体文件 mv /tmp/wqy-microhei.ttc /usr/share/fonts/truetype/wqy/ # 刷新字体缓存 fc-cache -fv # 验证字体安装 fc-list :lang=zh # 退出容器 exit # 重启应用(不重启容器) docker exec websoft-api-container pkill -f "java.*app.jar" ``` ### 方案三:使用其他基础镜像 如果Alpine Linux的字体支持仍有问题,可以考虑切换到Debian基础镜像: ```dockerfile FROM eclipse-temurin:17-jdk # 安装中文字体 RUN apt-get update && \ apt-get install -y --no-install-recommends \ fonts-wqy-microhei \ fonts-wqy-zenhei \ fontconfig && \ fc-cache -fv && \ rm -rf /var/lib/apt/lists/* ``` ## 代码改进说明 ### 1. 增强的字体检测逻辑 ```java // 检查多个中文字符,确保字体真正支持中文 if (font.canDisplay('中') && font.canDisplay('文')) { return font; } ``` ### 2. macOS字体优先级调整 ```java String[] chineseFonts = { "PingFang SC", // 苹方 (macOS) - 优先使用 "STHeiti", // 华文黑体 (macOS) "Hiragino Sans GB", // 冬青黑体 (macOS) "Microsoft YaHei", // 微软雅黑 (Windows) // ... }; ``` ### 3. 多层字体回退机制 ```java // 第一层:预定义字体列表 // 第二层:Java逻辑字体(SansSerif, Serif等) // 第三层:明确的错误提示 ``` ### 4. 详细的日志输出 ```java System.out.println("✓ 成功使用字体: " + fontName + " (字号: " + fontSize + ")"); System.err.println("✗ 严重警告:系统中没有找到任何支持中文的字体!"); ``` ## 验证修复 ### 1. 查看容器日志 ```bash docker logs -f websoft-api-container ``` 成功加载字体时会看到: ``` ✓ 成功使用字体: PingFang SC (字号: 26) ✓ 成功使用字体: PingFang SC (字号: 22) ``` ### 2. 测试证书生成 调用API生成新的证书,检查中文是否正常显示。 ### 3. 验证字体列表 在容器内执行: ```bash fc-list :lang=zh ``` 应该能看到已安装的中文字体列表。 ## macOS开发环境说明 如果在macOS上开发,系统已经包含以下中文字体: - PingFang SC(苹方,推荐) - STHeiti(华文黑体) - Hiragino Sans GB(冬青黑体) 代码已优化为优先使用这些字体。 ## 故障排查 ### 问题1:Docker镜像构建失败 **原因**:网络问题导致字体下载失败 **解决**: ```bash # 使用国内镜像或手动下载字体 wget https://ghproxy.com/https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc ``` ### 问题2:容器重启后字体丢失 **原因**:使用方案二安装的字体未持久化 **解决**:使用方案一重新构建镜像 ### 问题3:日志显示找不到字体 **原因**:字体安装未生效或路径错误 **解决**: ```bash # 检查字体文件是否存在 docker exec websoft-api-container ls -la /usr/share/fonts/truetype/wqy/ # 重建字体缓存 docker exec -u root websoft-api-container fc-cache -fv ``` ### 问题4:仍然显示乱码 **原因**:可能是图片已缓存 **解决**: 1. 清除浏览器缓存 2. 删除旧的证书图片文件 3. 重新生成证书(URL参数v会自动更新) ## 性能优化建议 1. **字体缓存**:首次加载后,字体会被JVM缓存,后续生成速度更快 2. **字体大小**:文泉驿微米黑字体文件约10MB,不会显著增加镜像大小 3. **镜像层优化**:字体安装合并到一个RUN命令中,减少镜像层数 ## 相关文件 - `/src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java` - 捐款证书生成逻辑 - `/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java` - 报名证书生成逻辑 - `/Dockerfile` - Docker镜像构建配置 ## 技术支持 如果问题仍未解决,请提供以下信息: 1. Docker镜像构建日志 2. 容器启动日志(包含字体加载信息) 3. 生成的证书图片链接 4. 系统环境信息(`docker version`, `docker info`)