From 6036869645b125c1268cc1f06435ed7cf8878e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Thu, 30 Oct 2025 14:46:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=E4=BC=98=E5=8C=96=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E6=94=AF=E6=8C=81=E5=92=8C=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在BszxBmServiceImpl和BszxPayServiceImpl中增强字体检测逻辑,确保正确显示中文 - 调整macOS字体优先级,优先使用PingFang SC等系统字体- 添加多层字体回退机制,包括预定义字体、逻辑字体和错误提示 - 更新Dockerfile,安装文泉驿微米黑字体以支持中文显示- 添加中文乱码修复指南文档,提供三种修复方案和故障排查方法 - 创建fix-chinese-font.sh脚本,用于在运行中的容器内安装中文字体 - 删除不再使用的SQL脚本和证书检查脚本- 改进日志输出,提供更详细的字体加载信息和错误提示 --- Dockerfile | 14 +- docs/chinese-font-fix-guide.md | 222 ++++++++++++++++++ scripts/fix-chinese-font.sh | 125 ++++++++++ .../bszx/service/impl/BszxBmServiceImpl.java | 37 ++- .../bszx/service/impl/BszxPayServiceImpl.java | 37 ++- .../resources/scripts/check_cert_paths.sh | 70 ------ .../sql/coupon_status_optimization.sql | 194 --------------- src/main/resources/sql/coupon_tables.sql | 78 ------ .../sql/create_dev_tenant_payment.sql | 206 ---------------- .../sql/fix_bigdecimal_null_values.sql | 107 --------- .../sql/fix_coupon_apply_item_table.sql | 101 -------- .../sql/fix_pay_status_102_error.sql | 133 ----------- .../sql/production_safe_payment_config.sql | 183 --------------- .../resources/sql/simple_fix_coupon_table.sql | 17 -- 14 files changed, 415 insertions(+), 1109 deletions(-) create mode 100644 docs/chinese-font-fix-guide.md create mode 100644 scripts/fix-chinese-font.sh delete mode 100644 src/main/resources/scripts/check_cert_paths.sh delete mode 100644 src/main/resources/sql/coupon_status_optimization.sql delete mode 100644 src/main/resources/sql/coupon_tables.sql delete mode 100644 src/main/resources/sql/create_dev_tenant_payment.sql delete mode 100644 src/main/resources/sql/fix_bigdecimal_null_values.sql delete mode 100644 src/main/resources/sql/fix_coupon_apply_item_table.sql delete mode 100644 src/main/resources/sql/fix_pay_status_102_error.sql delete mode 100644 src/main/resources/sql/production_safe_payment_config.sql delete mode 100644 src/main/resources/sql/simple_fix_coupon_table.sql diff --git a/Dockerfile b/Dockerfile index 7aba49b..84ae9f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,8 +10,18 @@ RUN mkdir -p /app/logs # 创建上传文件目录 RUN mkdir -p /app/uploads -# 安装wget用于健康检查,并添加应用用户(安全考虑) -RUN apk add --no-cache wget && \ +# 安装必要工具和中文字体支持 +# fontconfig: 字体配置库 +# ttf-dejavu: 包含DejaVu字体,支持中文显示 +# wqy-zenhei: 文泉驿正黑字体,开源中文字体 +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 && \ + # 创建应用用户(安全考虑) addgroup -g 1000 appgroup && \ adduser -D -u 1000 -G appgroup appuser diff --git a/docs/chinese-font-fix-guide.md b/docs/chinese-font-fix-guide.md new file mode 100644 index 0000000..ac9682d --- /dev/null +++ b/docs/chinese-font-fix-guide.md @@ -0,0 +1,222 @@ +# 捐款证书中文乱码修复指南 + +## 问题描述 +生成的捐款证书图片中,中文字符显示为乱码或方块,影响证书的正常使用。 + +问题示例: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`) diff --git a/scripts/fix-chinese-font.sh b/scripts/fix-chinese-font.sh new file mode 100644 index 0000000..1deac8b --- /dev/null +++ b/scripts/fix-chinese-font.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +############################################################################### +# 捐款证书中文乱码修复脚本 +# 用途:在运行中的Docker容器内安装中文字体 +# 适用于:无法重新构建镜像的紧急情况 +############################################################################### + +set -e # 遇到错误立即退出 + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 容器名称(可根据实际情况修改) +CONTAINER_NAME="websoft-api-container" + +echo -e "${GREEN}================================${NC}" +echo -e "${GREEN}中文字体修复脚本${NC}" +echo -e "${GREEN}================================${NC}" +echo "" + +# 检查容器是否存在 +echo -e "${YELLOW}步骤 1/6: 检查容器状态...${NC}" +if ! docker ps | grep -q "$CONTAINER_NAME"; then + echo -e "${RED}错误:容器 $CONTAINER_NAME 未运行!${NC}" + echo "当前运行的容器:" + docker ps --format "table {{.Names}}\t{{.Status}}" + echo "" + read -p "请输入正确的容器名称: " CONTAINER_NAME + if [ -z "$CONTAINER_NAME" ]; then + echo -e "${RED}容器名称不能为空,退出。${NC}" + exit 1 + fi +fi +echo -e "${GREEN}✓ 容器正在运行${NC}" +echo "" + +# 检查是否已安装字体 +echo -e "${YELLOW}步骤 2/6: 检查是否已安装中文字体...${NC}" +if docker exec "$CONTAINER_NAME" fc-list :lang=zh 2>/dev/null | grep -q "WenQuanYi"; then + echo -e "${GREEN}✓ 中文字体已安装${NC}" + docker exec "$CONTAINER_NAME" fc-list :lang=zh + echo "" + read -p "是否重新安装?(y/N): " REINSTALL + if [[ ! "$REINSTALL" =~ ^[Yy]$ ]]; then + echo "跳过安装,退出。" + exit 0 + fi +else + echo -e "${YELLOW}未检测到中文字体,开始安装...${NC}" +fi +echo "" + +# 安装字体工具 +echo -e "${YELLOW}步骤 3/6: 安装字体工具...${NC}" +docker exec -u root "$CONTAINER_NAME" sh -c "apk add --no-cache fontconfig ttf-dejavu wget" || { + echo -e "${RED}✗ 字体工具安装失败${NC}" + exit 1 +} +echo -e "${GREEN}✓ 字体工具安装成功${NC}" +echo "" + +# 下载中文字体 +echo -e "${YELLOW}步骤 4/6: 下载文泉驿微米黑字体...${NC}" +echo "正在从GitHub下载(约10MB),请稍候..." +docker exec -u root "$CONTAINER_NAME" sh -c " + wget -O /tmp/wqy-microhei.ttc https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc 2>&1 | grep -E 'Connecting|Length|saved' || true +" || { + echo -e "${YELLOW}GitHub下载失败,尝试使用代理...${NC}" + docker exec -u root "$CONTAINER_NAME" sh -c " + wget -O /tmp/wqy-microhei.ttc https://ghproxy.com/https://github.com/anthonyfok/fonts-wqy-microhei/raw/master/wqy-microhei.ttc + " || { + echo -e "${RED}✗ 字体下载失败${NC}" + echo "请检查网络连接或手动下载字体文件。" + exit 1 + } +} +echo -e "${GREEN}✓ 字体下载成功${NC}" +echo "" + +# 安装字体 +echo -e "${YELLOW}步骤 5/6: 安装字体文件...${NC}" +docker exec -u root "$CONTAINER_NAME" sh -c " + mkdir -p /usr/share/fonts/truetype/wqy && \ + mv /tmp/wqy-microhei.ttc /usr/share/fonts/truetype/wqy/ && \ + fc-cache -fv +" || { + echo -e "${RED}✗ 字体安装失败${NC}" + exit 1 +} +echo -e "${GREEN}✓ 字体安装成功${NC}" +echo "" + +# 验证安装 +echo -e "${YELLOW}步骤 6/6: 验证字体安装...${NC}" +FONT_COUNT=$(docker exec "$CONTAINER_NAME" fc-list :lang=zh | wc -l) +if [ "$FONT_COUNT" -gt 0 ]; then + echo -e "${GREEN}✓ 中文字体验证成功!${NC}" + echo "已安装的中文字体:" + docker exec "$CONTAINER_NAME" fc-list :lang=zh +else + echo -e "${RED}✗ 字体验证失败${NC}" + exit 1 +fi +echo "" + +# 完成提示 +echo -e "${GREEN}================================${NC}" +echo -e "${GREEN}修复完成!${NC}" +echo -e "${GREEN}================================${NC}" +echo "" +echo "后续步骤:" +echo "1. 不需要重启容器,字体已生效" +echo "2. 重新生成捐款证书即可看到效果" +echo "3. 如果仍有问题,请查看容器日志:" +echo " docker logs -f $CONTAINER_NAME" +echo "" +echo -e "${YELLOW}注意:${NC}" +echo "- 此修复方法在容器重启后会失效" +echo "- 建议后续使用更新后的Dockerfile重新构建镜像" +echo "- 详细文档请参考:docs/chinese-font-fix-guide.md" +echo "" diff --git a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java index d365a85..2544afd 100644 --- a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java +++ b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxBmServiceImpl.java @@ -184,32 +184,51 @@ public class BszxBmServiceImpl extends ServiceImpl impleme try { // 尝试使用系统中文字体 String[] chineseFonts = { + "Alibaba PuHuiTi 2.0", + "PingFang SC", // 苹方 (macOS) - 优先使用 + "STHeiti", // 华文黑体 (macOS) + "Hiragino Sans GB", // 冬青黑体 (macOS) "Microsoft YaHei", // 微软雅黑 (Windows) "SimHei", // 黑体 (Windows) "SimSun", // 宋体 (Windows) - "PingFang SC", // 苹方 (macOS) - "Hiragino Sans GB", // 冬青黑体 (macOS) "WenQuanYi Micro Hei", // 文泉驿微米黑 (Linux) "Noto Sans CJK SC", // 思源黑体 (Linux) + "Arial Unicode MS", // 支持Unicode的Arial "DejaVu Sans" // 备用字体 }; for (String fontName : chineseFonts) { Font font = new Font(fontName, Font.PLAIN, fontSize); // 检查字体是否能正确显示中文 - if (font.canDisplay('中')) { - System.out.println("使用字体: " + fontName); + if (font.canDisplay('中') && font.canDisplay('文')) { + System.out.println("✓ 成功使用字体: " + fontName + " (字号: " + fontSize + ")"); + return font; + } else { + System.out.println("✗ 字体不支持中文: " + fontName); + } + } + + // 如果没有找到合适的字体,尝试加载系统默认中文字体 + System.out.println("⚠ 警告:未找到预定义的中文字体,尝试使用系统默认字体"); + + // 尝试使用逻辑字体名称,这些在Java中通常会映射到系统字体 + String[] logicalFonts = {"SansSerif", "Serif", "Monospaced", "Dialog", "DialogInput"}; + for (String logicalFont : logicalFonts) { + Font font = new Font(logicalFont, Font.PLAIN, fontSize); + if (font.canDisplay('中') && font.canDisplay('文')) { + System.out.println("✓ 使用逻辑字体: " + logicalFont); return font; } } - // 如果没有找到合适的字体,使用默认字体 - System.out.println("警告:未找到支持中文的字体,使用默认字体"); - return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize); + // 最后的备选方案 + System.err.println("❌ 严重警告:系统中没有找到任何支持中文的字体!请安装中文字体包。"); + return new Font("SansSerif", Font.PLAIN, fontSize); } catch (Exception e) { - System.err.println("创建中文字体失败: " + e.getMessage()); - return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize); + System.err.println("❌ 创建中文字体失败: " + e.getMessage()); + e.printStackTrace(); + return new Font("SansSerif", Font.PLAIN, fontSize); } } diff --git a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java index d389330..12957c3 100644 --- a/src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java +++ b/src/main/java/com/gxwebsoft/bszx/service/impl/BszxPayServiceImpl.java @@ -238,32 +238,51 @@ public class BszxPayServiceImpl extends ServiceImpl impl try { // 尝试使用系统中文字体 String[] chineseFonts = { + "Alibaba PuHuiTi 2.0", + "PingFang SC", // 苹方 (macOS) - 优先使用 + "STHeiti", // 华文黑体 (macOS) + "Hiragino Sans GB", // 冬青黑体 (macOS) "Microsoft YaHei", // 微软雅黑 (Windows) "SimHei", // 黑体 (Windows) "SimSun", // 宋体 (Windows) - "PingFang SC", // 苹方 (macOS) - "Hiragino Sans GB", // 冬青黑体 (macOS) "WenQuanYi Micro Hei", // 文泉驿微米黑 (Linux) "Noto Sans CJK SC", // 思源黑体 (Linux) + "Arial Unicode MS", // 支持Unicode的Arial "DejaVu Sans" // 备用字体 }; for (String fontName : chineseFonts) { Font font = new Font(fontName, Font.PLAIN, fontSize); // 检查字体是否能正确显示中文 - if (font.canDisplay('中')) { - System.out.println("使用字体: " + fontName); + if (font.canDisplay('中') && font.canDisplay('文')) { + System.out.println("✓ 成功使用字体: " + fontName + " (字号: " + fontSize + ")"); + return font; + } else { + System.out.println("✗ 字体不支持中文: " + fontName); + } + } + + // 如果没有找到合适的字体,尝试加载系统默认中文字体 + System.out.println("⚠ 警告:未找到预定义的中文字体,尝试使用系统默认字体"); + + // 尝试使用逻辑字体名称,这些在Java中通常会映射到系统字体 + String[] logicalFonts = {"SansSerif", "Serif", "Monospaced", "Dialog", "DialogInput"}; + for (String logicalFont : logicalFonts) { + Font font = new Font(logicalFont, Font.PLAIN, fontSize); + if (font.canDisplay('中') && font.canDisplay('文')) { + System.out.println("✓ 使用逻辑字体: " + logicalFont); return font; } } - // 如果没有找到合适的字体,使用默认字体 - System.out.println("警告:未找到支持中文的字体,使用默认字体"); - return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize); + // 最后的备选方案 + System.err.println("❌ 严重警告:系统中没有找到任何支持中文的字体!请安装中文字体包。"); + return new Font("SansSerif", Font.PLAIN, fontSize); } catch (Exception e) { - System.err.println("创建中文字体失败: " + e.getMessage()); - return new Font(Font.SANS_SERIF, Font.PLAIN, fontSize); + System.err.println("❌ 创建中文字体失败: " + e.getMessage()); + e.printStackTrace(); + return new Font("SansSerif", Font.PLAIN, fontSize); } } } diff --git a/src/main/resources/scripts/check_cert_paths.sh b/src/main/resources/scripts/check_cert_paths.sh deleted file mode 100644 index 48aad98..0000000 --- a/src/main/resources/scripts/check_cert_paths.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# 检查证书文件路径的脚本 - -echo "=== 检查证书文件路径 ===" - -# 基础路径 -CERT_ROOT="/www/wwwroot/file.ws" -FILE_BASE="$CERT_ROOT" - -echo "证书根路径: $CERT_ROOT" -echo "文件基础路径: $FILE_BASE" - -# 检查根目录 -if [ -d "$CERT_ROOT" ]; then - echo "✓ 证书根目录存在: $CERT_ROOT" -else - echo "✗ 证书根目录不存在: $CERT_ROOT" -fi - -# 检查file目录 -if [ -d "$FILE_BASE" ]; then - echo "✓ 文件基础目录存在: $FILE_BASE" -else - echo "✗ 文件基础目录不存在: $FILE_BASE" -fi - -# 列出file目录下的内容 -echo "" -echo "=== file目录内容 ===" -if [ -d "$FILE_BASE" ]; then - ls -la "$FILE_BASE" -else - echo "file目录不存在" -fi - -# 查找所有.pem文件 -echo "" -echo "=== 查找所有.pem文件 ===" -find "$CERT_ROOT" -name "*.pem" -type f 2>/dev/null | head -20 - -# 查找所有.p12文件 -echo "" -echo "=== 查找所有.p12文件 ===" -find "$CERT_ROOT" -name "*.p12" -type f 2>/dev/null | head -20 - -# 检查特定文件 -SPECIFIC_FILE="/www/wwwroot/file.ws/20250727/c27fe16e08314431a56c3489818af64f.pem" -echo "" -echo "=== 检查特定文件 ===" -echo "文件路径: $SPECIFIC_FILE" -if [ -f "$SPECIFIC_FILE" ]; then - echo "✓ 文件存在" - echo "文件大小: $(stat -c%s "$SPECIFIC_FILE") bytes" - echo "文件权限: $(stat -c%A "$SPECIFIC_FILE")" - echo "文件所有者: $(stat -c%U:%G "$SPECIFIC_FILE")" - - # 检查文件内容 - echo "" - echo "文件前3行:" - head -3 "$SPECIFIC_FILE" - echo "..." - echo "文件后3行:" - tail -3 "$SPECIFIC_FILE" -else - echo "✗ 文件不存在" -fi - -echo "" -echo "=== 检查完成 ===" diff --git a/src/main/resources/sql/coupon_status_optimization.sql b/src/main/resources/sql/coupon_status_optimization.sql deleted file mode 100644 index 6a737b8..0000000 --- a/src/main/resources/sql/coupon_status_optimization.sql +++ /dev/null @@ -1,194 +0,0 @@ --- 优惠券状态管理优化SQL脚本 --- 作者: WebSoft --- 日期: 2025-01-15 --- 说明: 优化优惠券查询性能,添加必要的索引 - --- ======================================== --- 1. 添加索引优化查询性能 --- ======================================== - --- 用户优惠券表索引优化 -CREATE INDEX IF NOT EXISTS idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time); -CREATE INDEX IF NOT EXISTS idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0; -CREATE INDEX IF NOT EXISTS idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1; - --- 优惠券模板表索引优化 -CREATE INDEX IF NOT EXISTS idx_coupon_status_expire ON shop_coupon(status, expire_type, end_time); - --- ======================================== --- 2. 统一状态字段(如果需要数据迁移) --- ======================================== - --- 检查现有数据的状态一致性 -SELECT - '状态一致性检查' as check_item, - COUNT(*) as total_count, - SUM(CASE WHEN status = 0 AND is_use = 0 AND is_expire = 0 THEN 1 ELSE 0 END) as available_count, - SUM(CASE WHEN status = 1 AND is_use = 1 THEN 1 ELSE 0 END) as used_count, - SUM(CASE WHEN status = 2 OR is_expire = 1 THEN 1 ELSE 0 END) as expired_count, - SUM(CASE WHEN - (status = 0 AND (is_use = 1 OR is_expire = 1)) OR - (status = 1 AND is_use = 0) OR - (status = 2 AND is_expire = 0) - THEN 1 ELSE 0 END) as inconsistent_count -FROM shop_user_coupon; - --- 修复状态不一致的数据 -UPDATE shop_user_coupon -SET status = 1, is_use = 1 -WHERE status = 0 AND is_use = 1 AND is_expire = 0; - -UPDATE shop_user_coupon -SET status = 2, is_expire = 1 -WHERE status = 0 AND is_expire = 1; - -UPDATE shop_user_coupon -SET status = 2, is_expire = 1 -WHERE status IN (0, 1) AND end_time < NOW(); - --- ======================================== --- 3. 添加触发器自动更新过期状态(可选) --- ======================================== - -DELIMITER $$ - --- 创建触发器:在查询时自动检查过期状态 -CREATE TRIGGER IF NOT EXISTS tr_check_coupon_expire -BEFORE UPDATE ON shop_user_coupon -FOR EACH ROW -BEGIN - -- 如果是未使用状态且已过期,自动更新为过期状态 - IF NEW.status = 0 AND NEW.end_time < NOW() THEN - SET NEW.status = 2; - SET NEW.is_expire = 1; - END IF; -END$$ - -DELIMITER ; - --- ======================================== --- 4. 创建视图简化查询 --- ======================================== - --- 创建用户可用优惠券视图 -CREATE OR REPLACE VIEW v_user_available_coupons AS -SELECT - uc.*, - c.name as coupon_name, - c.description as coupon_description, - c.apply_range, - c.apply_range_config, - CASE - WHEN uc.end_time < NOW() THEN '已过期' - WHEN uc.status = 1 THEN '已使用' - WHEN uc.status = 0 THEN '可使用' - ELSE '未知状态' - END as status_desc -FROM shop_user_coupon uc -LEFT JOIN shop_coupon c ON uc.coupon_id = c.id -WHERE uc.deleted = 0; - --- 创建优惠券统计视图 -CREATE OR REPLACE VIEW v_coupon_statistics AS -SELECT - user_id, - COUNT(*) as total_count, - SUM(CASE WHEN status = 0 AND end_time >= NOW() THEN 1 ELSE 0 END) as available_count, - SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count, - SUM(CASE WHEN status = 2 OR end_time < NOW() THEN 1 ELSE 0 END) as expired_count -FROM shop_user_coupon -WHERE deleted = 0 -GROUP BY user_id; - --- ======================================== --- 5. 存储过程:批量处理过期优惠券 --- ======================================== - -DELIMITER $$ - -CREATE PROCEDURE IF NOT EXISTS sp_update_expired_coupons() -BEGIN - DECLARE done INT DEFAULT FALSE; - DECLARE update_count INT DEFAULT 0; - - -- 声明异常处理 - DECLARE CONTINUE HANDLER FOR SQLEXCEPTION - BEGIN - ROLLBACK; - RESIGNAL; - END; - - START TRANSACTION; - - -- 批量更新过期优惠券 - UPDATE shop_user_coupon - SET status = 2, is_expire = 1 - WHERE status = 0 - AND end_time < NOW() - AND deleted = 0; - - -- 获取更新数量 - SET update_count = ROW_COUNT(); - - COMMIT; - - -- 返回更新数量 - SELECT update_count as updated_count; - -END$$ - -DELIMITER ; - --- ======================================== --- 6. 性能监控查询 --- ======================================== - --- 查看优惠券状态分布 -SELECT - status, - CASE - WHEN status = 0 THEN '未使用' - WHEN status = 1 THEN '已使用' - WHEN status = 2 THEN '已过期' - ELSE '未知' - END as status_name, - COUNT(*) as count, - ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM shop_user_coupon WHERE deleted = 0), 2) as percentage -FROM shop_user_coupon -WHERE deleted = 0 -GROUP BY status -ORDER BY status; - --- 查看即将过期的优惠券(7天内) -SELECT - COUNT(*) as expiring_soon_count, - MIN(end_time) as earliest_expire_time, - MAX(end_time) as latest_expire_time -FROM shop_user_coupon -WHERE status = 0 - AND end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY) - AND deleted = 0; - --- 查看优惠券使用率统计 -SELECT - DATE(create_time) as date, - COUNT(*) as issued_count, - SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count, - ROUND(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as usage_rate -FROM shop_user_coupon -WHERE deleted = 0 - AND create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY) -GROUP BY DATE(create_time) -ORDER BY date DESC; - --- ======================================== --- 7. 清理和维护 --- ======================================== - --- 清理过期很久的优惠券记录(可选,谨慎使用) --- DELETE FROM shop_user_coupon --- WHERE status = 2 --- AND end_time < DATE_SUB(NOW(), INTERVAL 1 YEAR) --- AND deleted = 0; - -COMMIT; diff --git a/src/main/resources/sql/coupon_tables.sql b/src/main/resources/sql/coupon_tables.sql deleted file mode 100644 index 37dd8ed..0000000 --- a/src/main/resources/sql/coupon_tables.sql +++ /dev/null @@ -1,78 +0,0 @@ --- 优惠券功能相关数据库表 - --- 1. 更新优惠券模板表 -ALTER TABLE `shop_coupon` -ADD COLUMN `description` varchar(500) COMMENT '优惠券描述' AFTER `name`, -ADD COLUMN `total_count` int(11) DEFAULT -1 COMMENT '发放总数量(-1表示无限制)', -ADD COLUMN `issued_count` int(11) DEFAULT 0 COMMENT '已发放数量', -ADD COLUMN `limit_per_user` int(11) DEFAULT -1 COMMENT '每人限领数量(-1表示无限制)', -ADD COLUMN `enabled` tinyint(1) DEFAULT 1 COMMENT '是否启用(0禁用 1启用)', -MODIFY COLUMN `apply_range` int(11) DEFAULT 10 COMMENT '适用范围(10全部商品 20指定商品 30指定分类)', -MODIFY COLUMN `status` int(11) DEFAULT 0 COMMENT '状态, 0正常, 1禁用', -MODIFY COLUMN `user_id` int(11) COMMENT '创建用户ID'; - --- 2. 创建用户优惠券表 -CREATE TABLE `shop_user_coupon` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', - `coupon_id` int(11) NOT NULL COMMENT '优惠券模板ID', - `user_id` int(11) NOT NULL COMMENT '用户ID', - `name` varchar(100) NOT NULL COMMENT '优惠券名称', - `description` varchar(500) DEFAULT NULL COMMENT '优惠券描述', - `type` int(11) NOT NULL COMMENT '优惠券类型(10满减券 20折扣券 30免费劵)', - `reduce_price` decimal(10,2) DEFAULT NULL COMMENT '满减券-减免金额', - `discount` int(11) DEFAULT NULL COMMENT '折扣券-折扣率(0-100)', - `min_price` decimal(10,2) DEFAULT NULL COMMENT '最低消费金额', - `apply_range` int(11) DEFAULT 10 COMMENT '适用范围(10全部商品 20指定商品 30指定分类)', - `apply_range_config` text COMMENT '适用范围配置(json格式)', - `start_time` datetime DEFAULT NULL COMMENT '有效期开始时间', - `end_time` datetime DEFAULT NULL COMMENT '有效期结束时间', - `status` int(11) DEFAULT 0 COMMENT '使用状态(0未使用 1已使用 2已过期)', - `use_time` datetime DEFAULT NULL COMMENT '使用时间', - `order_id` bigint(20) DEFAULT NULL COMMENT '使用订单ID', - `order_no` varchar(50) DEFAULT NULL COMMENT '使用订单号', - `obtain_type` int(11) DEFAULT 10 COMMENT '获取方式(10主动领取 20系统发放 30活动赠送)', - `obtain_source` varchar(200) DEFAULT NULL COMMENT '获取来源描述', - `deleted` tinyint(1) DEFAULT 0 COMMENT '是否删除, 0否, 1是', - `tenant_id` int(11) DEFAULT NULL COMMENT '租户id', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', - PRIMARY KEY (`id`), - KEY `idx_user_id` (`user_id`), - KEY `idx_coupon_id` (`coupon_id`), - KEY `idx_status` (`status`), - KEY `idx_end_time` (`end_time`), - KEY `idx_order_id` (`order_id`), - KEY `idx_create_time` (`create_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户优惠券'; - --- 3. 创建优惠券使用记录表(可选,用于详细统计) -CREATE TABLE `shop_coupon_usage_log` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', - `user_coupon_id` bigint(20) NOT NULL COMMENT '用户优惠券ID', - `user_id` int(11) NOT NULL COMMENT '用户ID', - `order_id` bigint(20) NOT NULL COMMENT '订单ID', - `order_no` varchar(50) NOT NULL COMMENT '订单号', - `order_amount` decimal(10,2) NOT NULL COMMENT '订单金额', - `discount_amount` decimal(10,2) NOT NULL COMMENT '优惠金额', - `final_amount` decimal(10,2) NOT NULL COMMENT '最终金额', - `use_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '使用时间', - `tenant_id` int(11) DEFAULT NULL COMMENT '租户id', - PRIMARY KEY (`id`), - KEY `idx_user_id` (`user_id`), - KEY `idx_order_id` (`order_id`), - KEY `idx_use_time` (`use_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优惠券使用记录'; - --- 4. 插入示例优惠券模板数据 -INSERT INTO `shop_coupon` (`name`, `description`, `type`, `reduce_price`, `discount`, `min_price`, `total_count`, `issued_count`, `limit_per_user`, `expire_type`, `expire_day`, `apply_range`, `apply_range_config`, `enabled`, `sort_number`, `status`, `user_id`, `tenant_id`) VALUES -('新用户专享券', '新用户注册即可领取,满100减20', 10, 20.00, NULL, 100.00, 1000, 0, 1, 10, 30, 10, NULL, 1, 1, 0, 1, 1), -('满减优惠券', '全场通用,满200减50', 10, 50.00, NULL, 200.00, 500, 0, 2, 20, NULL, 10, NULL, 1, 2, 0, 1, 1), -('折扣优惠券', '全场9折优惠券', 20, NULL, 10, 50.00, 300, 0, 1, 10, 15, 10, NULL, 1, 3, 0, 1, 1), -('生日专享券', '生日当天专享,满50减30', 10, 30.00, NULL, 50.00, -1, 0, 1, 10, 7, 10, NULL, 1, 4, 0, 1, 1), -('消费返券', '消费满500返100优惠券', 10, 100.00, NULL, 300.00, -1, 0, -1, 10, 60, 10, NULL, 1, 5, 0, 1, 1); - --- 5. 创建索引优化查询性能 -CREATE INDEX `idx_shop_coupon_enabled_status` ON `shop_coupon` (`enabled`, `status`); -CREATE INDEX `idx_shop_coupon_expire_type` ON `shop_coupon` (`expire_type`, `start_time`, `end_time`); -CREATE INDEX `idx_shop_user_coupon_user_status` ON `shop_user_coupon` (`user_id`, `status`); -CREATE INDEX `idx_shop_user_coupon_expire` ON `shop_user_coupon` (`status`, `end_time`); diff --git a/src/main/resources/sql/create_dev_tenant_payment.sql b/src/main/resources/sql/create_dev_tenant_payment.sql deleted file mode 100644 index 4e395f7..0000000 --- a/src/main/resources/sql/create_dev_tenant_payment.sql +++ /dev/null @@ -1,206 +0,0 @@ --- 创建开发专用租户和支付配置 --- 用于隔离开发环境和生产环境的支付回调地址 - --- ======================================== --- 1. 创建开发专用租户(如果不存在) --- ======================================== - --- 检查是否已存在开发租户 -SELECT 'Checking for dev tenant...' as status; - --- 插入开发租户(租户ID使用 9999 避免与生产冲突) -INSERT IGNORE INTO sys_tenant ( - tenant_id, - tenant_name, - tenant_code, - contact_person, - contact_phone, - contact_email, - status, - deleted, - create_time, - update_time, - comments -) VALUES ( - 9999, - '开发测试租户', - 'DEV_TENANT', - '开发者', - '13800000000', - 'dev@websoft.top', - 1, - 0, - NOW(), - NOW(), - '专用于开发环境测试,不影响生产环境' -); - --- ======================================== --- 2. 创建开发环境专用支付配置 --- ======================================== - --- 微信支付开发配置 -INSERT IGNORE INTO sys_payment ( - name, - type, - code, - image, - wechat_type, - app_id, - mch_id, - api_key, - apiclient_cert, - apiclient_key, - pub_key, - pub_key_id, - merchant_serial_number, - notify_url, - comments, - sort_number, - status, - deleted, - tenant_id, - create_time, - update_time -) VALUES ( - '微信支付-开发环境', - 0, -- 微信支付 - 'wechat_dev', - '/static/images/wechat_pay.png', - 1, -- 普通商户 - 'wx1234567890abcdef', -- 开发环境AppID - '1234567890', -- 开发环境商户号 - 'your_dev_api_key_32_characters_long', - 'dev/wechat/apiclient_cert.pem', - 'dev/wechat/apiclient_key.pem', - 'dev/wechat/wechatpay_cert.pem', - 'your_pub_key_id', - 'your_merchant_serial_number', - 'http://frps-10550.s209.websoft.top/api/shop/shop-order/notify', -- 开发环境回调地址 - '开发环境专用配置,使用本地回调地址', - 1, - 1, -- 启用 - 0, -- 未删除 - 9999, -- 开发租户ID - NOW(), - NOW() -); - --- 支付宝开发配置 -INSERT IGNORE INTO sys_payment ( - name, - type, - code, - app_id, - mch_id, - api_key, - notify_url, - comments, - sort_number, - status, - deleted, - tenant_id, - create_time, - update_time -) VALUES ( - '支付宝-开发环境', - 1, -- 支付宝 - 'alipay_dev', - 'your_dev_alipay_app_id', - 'your_dev_alipay_mch_id', - 'your_dev_alipay_private_key', - 'http://frps-10550.s209.websoft.top/api/shop/shop-order/notify', -- 开发环境回调地址 - '开发环境专用支付宝配置', - 2, - 1, -- 启用 - 0, -- 未删除 - 9999, -- 开发租户ID - NOW(), - NOW() -); - --- ======================================== --- 3. 创建开发环境用户(可选) --- ======================================== - --- 创建开发专用用户 -INSERT IGNORE INTO sys_user ( - user_id, - username, - password, - nickname, - avatar, - sex, - phone, - email, - email_verified, - real_name, - id_card, - birthday, - department_id, - status, - deleted, - tenant_id, - create_time, - update_time, - comments -) VALUES ( - 99999, - 'dev_user', - '$2a$10$yKTnKzKqKqKqKqKqKqKqKOKqKqKqKqKqKqKqKqKqKqKqKqKqKqKqK', -- 密码: dev123456 - '开发测试用户', - '/static/images/default_avatar.png', - 1, - '13800000001', - 'dev_user@websoft.top', - 1, - '开发者', - '000000000000000000', - '1990-01-01', - 1, - 0, -- 正常状态 - 0, -- 未删除 - 9999, -- 开发租户ID - NOW(), - NOW(), - '开发环境专用测试用户' -); - --- ======================================== --- 4. 验证创建结果 --- ======================================== - --- 检查租户创建结果 -SELECT - 'Tenant Check' as check_type, - tenant_id, - tenant_name, - tenant_code, - status -FROM sys_tenant -WHERE tenant_id = 9999; - --- 检查支付配置创建结果 -SELECT - 'Payment Config Check' as check_type, - id, - name, - type, - notify_url, - tenant_id, - status -FROM sys_payment -WHERE tenant_id = 9999; - --- 检查用户创建结果 -SELECT - 'User Check' as check_type, - user_id, - username, - nickname, - tenant_id, - status -FROM sys_user -WHERE tenant_id = 9999; - -SELECT '开发环境配置创建完成!' as result; diff --git a/src/main/resources/sql/fix_bigdecimal_null_values.sql b/src/main/resources/sql/fix_bigdecimal_null_values.sql deleted file mode 100644 index 27388f9..0000000 --- a/src/main/resources/sql/fix_bigdecimal_null_values.sql +++ /dev/null @@ -1,107 +0,0 @@ --- 修复BigDecimal字段的null值问题 --- 将null值替换为0.00,避免JSON序列化异常 - --- ======================================== --- 1. 修复用户优惠券表的null值 --- ======================================== - --- 检查当前null值情况 -SELECT - 'shop_user_coupon null值检查' as table_name, - COUNT(*) as total_records, - COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price, - COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price -FROM shop_user_coupon; - --- 修复reduce_price字段的null值 -UPDATE shop_user_coupon -SET reduce_price = 0.00 -WHERE reduce_price IS NULL; - --- 修复min_price字段的null值 -UPDATE shop_user_coupon -SET min_price = 0.00 -WHERE min_price IS NULL; - --- ======================================== --- 2. 修复优惠券模板表的null值 --- ======================================== - --- 检查当前null值情况 -SELECT - 'shop_coupon null值检查' as table_name, - COUNT(*) as total_records, - COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price, - COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price -FROM shop_coupon; - --- 修复reduce_price字段的null值 -UPDATE shop_coupon -SET reduce_price = 0.00 -WHERE reduce_price IS NULL; - --- 修复min_price字段的null值 -UPDATE shop_coupon -SET min_price = 0.00 -WHERE min_price IS NULL; - --- ======================================== --- 3. 设置字段默认值(可选) --- ======================================== - --- 为用户优惠券表字段设置默认值 -ALTER TABLE shop_user_coupon -MODIFY COLUMN reduce_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '满减券-减免金额'; - -ALTER TABLE shop_user_coupon -MODIFY COLUMN min_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '最低消费金额'; - --- 为优惠券模板表字段设置默认值 -ALTER TABLE shop_coupon -MODIFY COLUMN reduce_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '满减券-减免金额'; - -ALTER TABLE shop_coupon -MODIFY COLUMN min_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '最低消费金额'; - --- ======================================== --- 4. 验证修复结果 --- ======================================== - --- 检查修复后的情况 -SELECT - 'shop_user_coupon 修复后检查' as table_name, - COUNT(*) as total_records, - COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price, - COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price, - MIN(reduce_price) as min_reduce_price, - MIN(min_price) as min_min_price -FROM shop_user_coupon; - -SELECT - 'shop_coupon 修复后检查' as table_name, - COUNT(*) as total_records, - COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price, - COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price, - MIN(reduce_price) as min_reduce_price, - MIN(min_price) as min_min_price -FROM shop_coupon; - --- ======================================== --- 5. 检查其他可能的BigDecimal字段 --- ======================================== - --- 检查订单相关表的BigDecimal字段 -SELECT - 'shop_order BigDecimal字段检查' as check_type, - COUNT(*) as total_records, - COUNT(CASE WHEN order_price IS NULL THEN 1 END) as null_order_price, - COUNT(CASE WHEN pay_price IS NULL THEN 1 END) as null_pay_price -FROM shop_order; - --- 如果发现null值,可以执行以下修复 -/* -UPDATE shop_order SET order_price = 0.00 WHERE order_price IS NULL; -UPDATE shop_order SET pay_price = 0.00 WHERE pay_price IS NULL; -*/ - -SELECT 'BigDecimal null值修复完成!' as result; diff --git a/src/main/resources/sql/fix_coupon_apply_item_table.sql b/src/main/resources/sql/fix_coupon_apply_item_table.sql deleted file mode 100644 index c44e98f..0000000 --- a/src/main/resources/sql/fix_coupon_apply_item_table.sql +++ /dev/null @@ -1,101 +0,0 @@ --- 修复优惠券适用商品表字段缺失问题 --- 作者: WebSoft --- 日期: 2025-01-15 --- 说明: 添加缺失的 goods_id 和 category_id 字段 - --- ======================================== --- 1. 检查表是否存在 --- ======================================== -SELECT 'Checking table existence...' as status; - --- ======================================== --- 2. 添加缺失的字段 --- ======================================== - --- 添加 goods_id 字段(如果不存在) -SET @sql = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'shop_coupon_apply_item' - AND COLUMN_NAME = 'goods_id') = 0, - 'ALTER TABLE shop_coupon_apply_item ADD COLUMN goods_id INT(11) NULL COMMENT "商品ID" AFTER coupon_id;', - 'SELECT "goods_id column already exists" as result;' -)); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 添加 category_id 字段(如果不存在) -SET @sql = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'shop_coupon_apply_item' - AND COLUMN_NAME = 'category_id') = 0, - 'ALTER TABLE shop_coupon_apply_item ADD COLUMN category_id INT(11) NULL COMMENT "分类ID" AFTER goods_id;', - 'SELECT "category_id column already exists" as result;' -)); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- ======================================== --- 3. 更新现有数据(如果需要) --- ======================================== - --- 如果表中有数据但 goods_id 为空,可以根据业务逻辑设置默认值 --- 这里只是示例,实际需要根据业务需求调整 -UPDATE shop_coupon_apply_item -SET goods_id = pk -WHERE goods_id IS NULL AND type = 1 AND pk IS NOT NULL; - --- ======================================== --- 4. 添加索引优化查询性能 --- ======================================== - --- 添加 goods_id 索引 -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_goods ON shop_coupon_apply_item(coupon_id, goods_id); - --- 添加 category_id 索引 -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_category ON shop_coupon_apply_item(coupon_id, category_id); - --- 添加类型索引 -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_type ON shop_coupon_apply_item(coupon_id, type); - --- ======================================== --- 5. 验证修复结果 --- ======================================== - --- 检查表结构 -SELECT - COLUMN_NAME, - DATA_TYPE, - IS_NULLABLE, - COLUMN_DEFAULT, - COLUMN_COMMENT -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'shop_coupon_apply_item' -ORDER BY ORDINAL_POSITION; - --- 检查数据 -SELECT - 'Data check' as check_type, - COUNT(*) as total_records, - COUNT(goods_id) as records_with_goods_id, - COUNT(category_id) as records_with_category_id -FROM shop_coupon_apply_item; - --- ======================================== --- 6. 创建示例数据(可选) --- ======================================== - --- 如果表为空,插入一些示例数据用于测试 -INSERT IGNORE INTO shop_coupon_apply_item -(coupon_id, goods_id, category_id, type, status, tenant_id, create_time, update_time) -VALUES -(1, 1, NULL, 1, 0, 1, NOW(), NOW()), -(1, 2, NULL, 1, 0, 1, NOW(), NOW()), -(2, NULL, 1, 2, 0, 1, NOW(), NOW()), -(2, NULL, 2, 2, 0, 1, NOW(), NOW()); - -SELECT 'Database fix completed successfully!' as result; diff --git a/src/main/resources/sql/fix_pay_status_102_error.sql b/src/main/resources/sql/fix_pay_status_102_error.sql deleted file mode 100644 index 5d9b297..0000000 --- a/src/main/resources/sql/fix_pay_status_102_error.sql +++ /dev/null @@ -1,133 +0,0 @@ --- 修复支付状态错误:将错误的102值修正为正确的1(已付款) --- --- 问题原因:ShopOrderMapper.xml中的updateByOutTradeNo方法错误地将payType的值赋给了payStatus字段 --- 修复内容: --- 1. 将所有payStatus=102的记录修改为payStatus=1(已付款) --- 2. 验证修复结果 - --- ======================================== --- 1. 检查当前问题数据 --- ======================================== - --- 查看所有payStatus=102的订单 -SELECT - '=== 问题数据检查 ===' as section, - order_id, - order_no, - pay_type, - pay_status, - pay_time, - transaction_id, - tenant_id, - create_time -FROM shop_order -WHERE pay_status = 102 -ORDER BY create_time DESC; - --- 统计问题数据数量 -SELECT - '=== 问题统计 ===' as section, - COUNT(*) as total_error_records, - COUNT(DISTINCT tenant_id) as affected_tenants, - MIN(create_time) as earliest_error, - MAX(create_time) as latest_error -FROM shop_order -WHERE pay_status = 102; - --- 按租户统计问题数据 -SELECT - '=== 按租户统计 ===' as section, - tenant_id, - COUNT(*) as error_count, - MIN(create_time) as first_error, - MAX(create_time) as last_error -FROM shop_order -WHERE pay_status = 102 -GROUP BY tenant_id -ORDER BY error_count DESC; - --- ======================================== --- 2. 备份问题数据(可选) --- ======================================== - --- 创建备份表(如果需要) --- CREATE TABLE shop_order_pay_status_backup_20250830 AS --- SELECT * FROM shop_order WHERE pay_status = 102; - --- ======================================== --- 3. 修复数据 --- ======================================== - --- 修复:将payStatus=102的记录改为payStatus=1(已付款) --- 注意:只修复那些有支付时间和交易号的订单(确实已支付的订单) -UPDATE shop_order -SET pay_status = 1 -WHERE pay_status = 102 - AND pay_time IS NOT NULL - AND transaction_id IS NOT NULL - AND transaction_id != ''; - --- 对于没有支付时间或交易号的订单,设置为未付款状态 -UPDATE shop_order -SET pay_status = 0 -WHERE pay_status = 102 - AND (pay_time IS NULL OR transaction_id IS NULL OR transaction_id = ''); - --- ======================================== --- 4. 验证修复结果 --- ======================================== - --- 检查是否还有payStatus=102的记录 -SELECT - '=== 修复结果检查 ===' as section, - COUNT(*) as remaining_error_records -FROM shop_order -WHERE pay_status = 102; - --- 验证修复后的数据分布 -SELECT - '=== 支付状态分布 ===' as section, - pay_status, - COUNT(*) as record_count, - CASE - WHEN pay_status = 0 THEN '未付款' - WHEN pay_status = 1 THEN '已付款' - ELSE CONCAT('异常状态: ', pay_status) - END as status_desc -FROM shop_order -GROUP BY pay_status -ORDER BY pay_status; - --- 检查最近修复的订单 -SELECT - '=== 最近修复的订单 ===' as section, - order_id, - order_no, - pay_type, - pay_status, - pay_time, - transaction_id, - tenant_id -FROM shop_order -WHERE pay_status = 1 - AND pay_time IS NOT NULL - AND transaction_id IS NOT NULL - AND update_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR) -ORDER BY update_time DESC -LIMIT 10; - --- ======================================== --- 5. 生成修复报告 --- ======================================== - -SELECT - '=== 修复完成报告 ===' as section, - CONCAT( - '问题原因:ShopOrderMapper.xml中updateByOutTradeNo方法错误地将payType值赋给payStatus字段\n', - '修复方案:\n', - '1. 修复了XML映射文件中的错误:pay_status = #{param.payType} -> pay_status = #{param.payStatus}\n', - '2. 修复了数据库中已存在的错误数据\n', - '3. 建议:检查其他可能的类似错误\n' - ) as fix_summary; - -SELECT '✅ 支付状态修复完成!请验证支付回调功能是否正常工作。' as result; diff --git a/src/main/resources/sql/production_safe_payment_config.sql b/src/main/resources/sql/production_safe_payment_config.sql deleted file mode 100644 index d85f8bd..0000000 --- a/src/main/resources/sql/production_safe_payment_config.sql +++ /dev/null @@ -1,183 +0,0 @@ --- 生产环境安全的支付配置脚本 --- 此脚本可以安全地在生产数据库执行 --- 不会创建测试数据,只添加必要的配置支持 - --- ======================================== --- 1. 检查当前环境(手动确认) --- ======================================== -SELECT - '请确认这是您要修改的数据库' as warning, - DATABASE() as current_database, - NOW() as execution_time; - --- 暂停执行,让用户确认 --- 如果确认无误,请删除下面这行注释继续执行 --- SELECT 'Please confirm this is the correct database before proceeding' as confirmation_required; - --- ======================================== --- 2. 添加支付配置表字段(如果不存在) --- ======================================== - --- 检查是否需要添加环境标识字段 -SELECT - CASE - WHEN COUNT(*) = 0 THEN '需要添加environment字段' - ELSE '环境字段已存在' - END as environment_field_status -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'sys_payment' - AND COLUMN_NAME = 'environment'; - --- 添加环境标识字段(如果不存在) -SET @sql = (SELECT IF( - (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'sys_payment' - AND COLUMN_NAME = 'environment') = 0, - 'ALTER TABLE sys_payment ADD COLUMN environment VARCHAR(20) DEFAULT "prod" COMMENT "环境标识(dev/test/prod)" AFTER tenant_id;', - 'SELECT "environment column already exists" as result;' -)); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- ======================================== --- 3. 为现有支付配置添加环境标识 --- ======================================== - --- 将现有配置标记为生产环境 -UPDATE sys_payment -SET environment = 'prod' -WHERE environment IS NULL OR environment = ''; - --- ======================================== --- 4. 创建开发环境配置的安全方式 --- ======================================== - --- 方式1:复制现有生产配置作为开发模板(推荐) --- 注意:这里使用您现有的租户ID,不创建新租户 - --- 获取当前生产环境的微信支付配置 -SELECT - '当前微信支付配置' as config_type, - id, - name, - app_id, - mch_id, - notify_url, - tenant_id, - environment -FROM sys_payment -WHERE type = 0 AND status = 1 AND deleted = 0 -ORDER BY id DESC LIMIT 1; - --- 获取当前生产环境的支付宝配置 -SELECT - '当前支付宝配置' as config_type, - id, - name, - app_id, - mch_id, - notify_url, - tenant_id, - environment -FROM sys_payment -WHERE type = 1 AND status = 1 AND deleted = 0 -ORDER BY id DESC LIMIT 1; - --- ======================================== --- 5. 手动创建开发配置的SQL模板 --- ======================================== - --- 以下SQL需要您手动修改参数后执行 --- 请根据上面查询的结果,修改相应的参数 - -/* --- 微信支付开发配置模板(请修改参数后执行) -INSERT INTO sys_payment ( - name, type, code, image, wechat_type, - app_id, mch_id, api_key, apiclient_cert, apiclient_key, - pub_key, pub_key_id, merchant_serial_number, notify_url, - comments, sort_number, status, deleted, tenant_id, environment, - create_time, update_time -) VALUES ( - '微信支付-开发环境', - 0, -- 微信支付 - 'wechat_dev', - '/static/images/wechat_pay.png', - 1, -- 普通商户 - 'YOUR_DEV_APP_ID', -- 请替换为您的开发环境AppID - 'YOUR_DEV_MCH_ID', -- 请替换为您的开发环境商户号 - 'YOUR_DEV_API_KEY', -- 请替换为您的开发环境API密钥 - 'dev/wechat/apiclient_cert.pem', - 'dev/wechat/apiclient_key.pem', - 'dev/wechat/wechatpay_cert.pem', - 'YOUR_DEV_PUB_KEY_ID', - 'YOUR_DEV_MERCHANT_SERIAL', - 'http://frps-10550.s209.websoft.top/api/shop/shop-order/notify', -- 开发环境回调 - '开发环境专用配置', - 1, - 1, -- 启用 - 0, -- 未删除 - YOUR_TENANT_ID, -- 请替换为您的租户ID - 'dev', -- 开发环境标识 - NOW(), - NOW() -); -*/ - --- ======================================== --- 6. 更安全的方案:仅更新现有配置的回调地址 --- ======================================== - --- 查看当前回调地址 -SELECT - '当前回调地址检查' as check_type, - id, - name, - type, - notify_url, - tenant_id, - environment -FROM sys_payment -WHERE status = 1 AND deleted = 0; - --- 如果您只是想临时修改回调地址进行调试,可以使用以下SQL: --- 注意:请先备份原始配置! - -/* --- 备份当前配置 -CREATE TABLE IF NOT EXISTS sys_payment_backup AS -SELECT *, NOW() as backup_time FROM sys_payment WHERE status = 1; - --- 临时修改回调地址(请谨慎使用) -UPDATE sys_payment -SET notify_url = 'http://frps-10550.s209.websoft.top/api/shop/shop-order/notify' -WHERE type = 0 AND tenant_id = YOUR_TENANT_ID AND status = 1; - --- 恢复原始配置的SQL(调试完成后执行) -UPDATE sys_payment -SET notify_url = 'https://cms-api.websoft.top/api/shop/shop-order/notify' -WHERE type = 0 AND tenant_id = YOUR_TENANT_ID AND status = 1; -*/ - --- ======================================== --- 7. 验证配置 --- ======================================== - --- 检查所有支付配置 -SELECT - '最终配置检查' as check_type, - id, - name, - type, - notify_url, - tenant_id, - environment, - status -FROM sys_payment -WHERE deleted = 0 -ORDER BY tenant_id, type; - -SELECT '生产环境安全配置完成!请根据注释中的模板手动创建开发配置。' as result; diff --git a/src/main/resources/sql/simple_fix_coupon_table.sql b/src/main/resources/sql/simple_fix_coupon_table.sql deleted file mode 100644 index 6bb5abf..0000000 --- a/src/main/resources/sql/simple_fix_coupon_table.sql +++ /dev/null @@ -1,17 +0,0 @@ --- 简单修复优惠券适用商品表字段缺失问题 --- 执行前请备份数据库 - --- 1. 添加缺失的字段 -ALTER TABLE shop_coupon_apply_item -ADD COLUMN IF NOT EXISTS goods_id INT(11) NULL COMMENT '商品ID' AFTER coupon_id; - -ALTER TABLE shop_coupon_apply_item -ADD COLUMN IF NOT EXISTS category_id INT(11) NULL COMMENT '分类ID' AFTER goods_id; - --- 2. 添加索引 -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_goods ON shop_coupon_apply_item(coupon_id, goods_id); -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_category ON shop_coupon_apply_item(coupon_id, category_id); -CREATE INDEX IF NOT EXISTS idx_coupon_apply_item_type ON shop_coupon_apply_item(coupon_id, type); - --- 3. 检查表结构 -DESCRIBE shop_coupon_apply_item;