Files
zyt/GANCAO_FIX_SUMMARY.md
T
2026-04-15 16:31:25 +08:00

7.1 KiB
Raw Blame History

甘草 API "Array to string conversion" 错误修复总结

问题描述

在 Linux 服务器上调用甘草处方下单接口时,返回错误:

{"code":2,"message":"Array to string conversion"}

已完成的修复

1. 代码层面修复

GancaoScmRecipelService.php

  • 修复 express_type 字段:确保是字符串而不是数组
  • 修复 callback_url 字段:确保是字符串而不是数组
  • 修复患者年龄格式:从 sprintf('%d.00', $ageInt) 改为 (string) $ageInt
  • 优化 doct_advice 字段处理:确保所有子字段都是字符串
  • 添加调试日志:记录发送的完整负载

PrescriptionOrderLogic.php

  • 修复 $appNo 变量引用问题
  • 添加详细错误日志:记录失败时的完整请求和响应
  • 添加 use think\facade\Log; 导入

PrescriptionOrderController.php

  • 添加 try-catch 异常处理
  • 添加返回值类型检查
  • 添加详细日志记录

2. 诊断工具

创建了三个诊断脚本:

  1. test_gancao_config.php - 配置检查脚本

    • 检查所有配置项是否存在
    • 检查配置值类型是否正确
    • 检查是否有数组值被错误地用作字符串
    • 测试 JSON 编码
  2. diagnose_gancao_payload.php - 负载诊断脚本

    • 测试 buildPreviewPayload 方法
    • 测试 buildSubmitPayload 方法
    • 检查每个字段的类型
    • 测试 JSON 编码
    • 保存负载到文件以便检查
  3. 文档

    • GANCAO_API_FIX.md - 初步修复说明
    • GANCAO_ARRAY_TO_STRING_FIX.md - 完整解决方案
    • GANCAO_FIX_SUMMARY.md - 本文档

下一步操作

步骤 1: 上传修复后的代码到服务器

# 上传修改的文件
scp server/app/common/service/gancao/GancaoScmRecipelService.php user@server:/path/to/server/app/common/service/gancao/
scp server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php user@server:/path/to/server/app/adminapi/logic/tcm/
scp server/app/adminapi/controller/tcm/PrescriptionOrderController.php user@server:/path/to/server/app/adminapi/controller/tcm/

# 上传诊断脚本
scp test_gancao_config.php user@server:/path/to/
scp diagnose_gancao_payload.php user@server:/path/to/

步骤 2: 在服务器上运行配置检查

ssh user@server
cd /path/to/your/project

# 运行配置检查
php test_gancao_config.php

期望输出

=== 甘草配置检查 ===

1. 检查配置是否存在:
   ✓ 配置已加载

2. 检查各项配置:
   - enabled: ✓ boolean = true
   - gateway_url: ✓ string = https://...
   - gateway_ak: ✓ string = xxx
   - gateway_sk: ✓ string = xxx
   - biz_ak: ✓ string = xxx
   - biz_sk: ✓ string = xxx
   - callback_url: ✓ string = https://...
   - express_type: ✓ string = sf
   - cradle_store: ✓ string = xxx
   - df_id: ✓ integer = 101

...

=== 检查结果: ✓ 配置正常 ===

如果看到 ⚠️

  • 记录哪个字段有问题
  • 检查 .env 文件中该字段的配置
  • 修复后重新运行检查

步骤 3: 运行负载诊断

php diagnose_gancao_payload.php

这会:

  • 测试负载构建过程
  • 检查每个字段的类型
  • 测试 JSON 编码
  • 生成一个 JSON 文件(gancao_payload_YYYYMMDDHHMMSS.json

检查生成的 JSON 文件,确保:

  • 没有字段的值是 "Array"
  • 所有字符串字段都是字符串
  • 所有数组字段都是数组

步骤 4: 清除缓存

cd server
php think clear

# 或手动删除
rm -rf runtime/cache/*
rm -rf runtime/temp/*

步骤 5: 重启服务

# PHP-FPM
sudo systemctl restart php-fpm

# Nginx
sudo systemctl restart nginx

步骤 6: 测试接口

# 查看实时日志
tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i gancao

在另一个终端调用接口:

curl -X POST https://your-domain.com/api/tcm.prescriptionOrder/submitGancaoRecipel \
  -H "Content-Type: application/json" \
  -H "token: your_token" \
  -d '{"id": 订单ID}'

步骤 7: 检查日志

日志中应该看到:

成功的情况

[info] Gancao CTM_SUBMIT_RECIPEL payload: {...}
[info] submitGancaoRecipel success: {...}

失败的情况

[error] Gancao CTM_SUBMIT failed: {...}
[error] submitGancaoRecipel exception: {...}

常见问题排查

问题 1: 配置检查显示某个字段是数组

解决方案

  1. 编辑 .env 文件
  2. 找到该字段的配置行
  3. 移除 [] 和多余的引号
  4. 示例:
    # 错误
    GANCAO_SCM_EXPRESS_TYPE=["sf"]
    
    # 正确
    GANCAO_SCM_EXPRESS_TYPE=sf
    
  5. 保存后清除缓存并重启服务

问题 2: JSON 中包含 "Array" 字符串

解决方案

  1. 运行 diagnose_gancao_payload.php 找出是哪个字段
  2. 检查该字段在代码中的处理
  3. 确保使用 (string) 强制转换
  4. 检查配置文件中该字段的值

问题 3: 仍然报 "Array to string conversion"

可能原因

  1. 缓存未清除
  2. 服务未重启
  3. 上传的文件未生效
  4. 配置文件有语法错误

排查步骤

  1. 确认文件已上传:ls -la server/app/common/service/gancao/GancaoScmRecipelService.php
  2. 检查文件修改时间:stat server/app/common/service/gancao/GancaoScmRecipelService.php
  3. 清除所有缓存:rm -rf server/runtime/*
  4. 重启所有服务
  5. 检查 PHP 错误日志:tail -f /var/log/php-fpm/error.log

问题 4: 配置检查通过但接口仍然失败

排查步骤

  1. 检查日志中的完整错误信息
  2. 查看 Gancao CTM_SUBMIT_RECIPEL payload 日志,确认发送的数据
  3. 检查甘草 API 返回的错误信息
  4. 确认药材 ID 映射是否正确
  5. 确认处方数据是否完整

验证修复成功

修复成功的标志:

  1. test_gancao_config.php 全部通过
  2. diagnose_gancao_payload.php 全部通过
  3. 接口返回成功:
    {
      "code": 1,
      "msg": "甘草药方上传成功",
      "data": {
        "recipel_order_no": "GC...",
        "app_order_no": "PO...",
        "fee": {...}
      }
    }
    
  4. 日志显示 submitGancaoRecipel success
  5. 数据库 prescription_order 表中 gancao_reciperl_order_no 字段已更新

需要进一步帮助

如果以上步骤都无法解决问题,请提供:

  1. 配置检查输出

    php test_gancao_config.php > config_check.txt 2>&1
    
  2. 负载诊断输出

    php diagnose_gancao_payload.php > payload_check.txt 2>&1
    
  3. 错误日志

    tail -100 server/runtime/log/$(date +%Y%m%d).log > error.log
    
  4. 接口响应

    curl -X POST ... > response.json 2>&1
    
  5. .env 配置(隐藏敏感信息):

    grep GANCAO_SCM .env > gancao_config.txt
    

将这些文件发送给技术支持进行分析。

总结

这次修复主要解决了配置值类型错误的问题。关键点:

  1. 配置必须是正确的类型:字符串字段不能是数组
  2. .env 格式很重要:不要使用 JSON 语法或数组语法
  3. 缓存必须清除:修改配置后必须清除缓存
  4. 日志很重要:添加了详细日志帮助排查问题

希望这次修复能解决你的问题!