# 甘草 API "Array to string conversion" 错误修复总结 ## 问题描述 在 Linux 服务器上调用甘草处方下单接口时,返回错误: ```json {"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: 上传修复后的代码到服务器 ```bash # 上传修改的文件 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: 在服务器上运行配置检查 ```bash 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: 运行负载诊断 ```bash php diagnose_gancao_payload.php ``` 这会: - 测试负载构建过程 - 检查每个字段的类型 - 测试 JSON 编码 - 生成一个 JSON 文件(`gancao_payload_YYYYMMDDHHMMSS.json`) 检查生成的 JSON 文件,确保: - 没有字段的值是 `"Array"` - 所有字符串字段都是字符串 - 所有数组字段都是数组 ### 步骤 4: 清除缓存 ```bash cd server php think clear # 或手动删除 rm -rf runtime/cache/* rm -rf runtime/temp/* ``` ### 步骤 5: 重启服务 ```bash # PHP-FPM sudo systemctl restart php-fpm # Nginx sudo systemctl restart nginx ``` ### 步骤 6: 测试接口 ```bash # 查看实时日志 tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i gancao ``` 在另一个终端调用接口: ```bash 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. 示例: ```env # 错误 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. ✅ 接口返回成功: ```json { "code": 1, "msg": "甘草药方上传成功", "data": { "recipel_order_no": "GC...", "app_order_no": "PO...", "fee": {...} } } ``` 4. ✅ 日志显示 `submitGancaoRecipel success` 5. ✅ 数据库 `prescription_order` 表中 `gancao_reciperl_order_no` 字段已更新 ## 需要进一步帮助 如果以上步骤都无法解决问题,请提供: 1. **配置检查输出**: ```bash php test_gancao_config.php > config_check.txt 2>&1 ``` 2. **负载诊断输出**: ```bash php diagnose_gancao_payload.php > payload_check.txt 2>&1 ``` 3. **错误日志**: ```bash tail -100 server/runtime/log/$(date +%Y%m%d).log > error.log ``` 4. **接口响应**: ```bash curl -X POST ... > response.json 2>&1 ``` 5. **`.env` 配置**(隐藏敏感信息): ```bash grep GANCAO_SCM .env > gancao_config.txt ``` 将这些文件发送给技术支持进行分析。 ## 总结 这次修复主要解决了配置值类型错误的问题。关键点: 1. **配置必须是正确的类型**:字符串字段不能是数组 2. **`.env` 格式很重要**:不要使用 JSON 语法或数组语法 3. **缓存必须清除**:修改配置后必须清除缓存 4. **日志很重要**:添加了详细日志帮助排查问题 希望这次修复能解决你的问题!