# 甘草 API "Array to string conversion" 错误完整解决方案 ## 问题现象 调用甘草处方下单接口时返回: ```json {"code":2,"message":"Array to string conversion"} ``` ## 根本原因分析 "Array to string conversion" 错误通常发生在以下情况: 1. **配置文件中的值被错误地解析为数组** - 例如:`.env` 中 `GANCAO_SCM_EXPRESS_TYPE=["sf"]` 会被解析为数组 - 正确应该是:`GANCAO_SCM_EXPRESS_TYPE=sf` 2. **PHP 尝试将数组转换为字符串** - 在字符串拼接、JSON 编码或其他操作中 3. **配置读取问题** - ThinkPHP 的配置解析可能将某些值错误地转换为数组 ## 完整修复步骤 ### 步骤 1: 检查配置文件 运行配置检查脚本: ```bash cd /path/to/your/project php test_gancao_config.php ``` 这个脚本会检查: - 所有必需的配置项是否存在 - 配置值的类型是否正确 - 是否有数组值被错误地用作字符串 ### 步骤 2: 修复 .env 配置 确保 `.env` 文件中的甘草配置格式正确: ```env # 甘草配置必须写在文件顶部,或者使用 [GANCAO_SCM] 分区 # 不要写在 [trtc] 等其他分区内 GANCAO_SCM_ENABLED=true GANCAO_SCM_GATEWAY_URL=https://your-gateway-url.com GANCAO_SCM_GATEWAY_AK=your_gateway_ak GANCAO_SCM_GATEWAY_SK=your_gateway_sk_16chars GANCAO_SCM_BIZ_AK=your_biz_ak GANCAO_SCM_BIZ_SK=your_biz_sk GANCAO_SCM_CALLBACK_URL=https://your-domain.com/api/gancao/callback GANCAO_SCM_EXPRESS_TYPE=sf GANCAO_SCM_CRADLE_STORE=your_store_name GANCAO_SCM_DF_ID=101 # 可选配置 GANCAO_SCM_DEFAULT_IS_DECOCT=1 GANCAO_SCM_DEFAULT_TIMES_PER_DAY=2 GANCAO_SCM_DEFAULT_NUM_PER_PACK=2 GANCAO_SCM_DEFAULT_DOSE_ML=150 ``` **重要注意事项:** 1. ❌ **错误示例**(会导致数组转字符串错误): ```env GANCAO_SCM_EXPRESS_TYPE=["sf"] GANCAO_SCM_CALLBACK_URL=["https://..."] ``` 2. ✅ **正确示例**: ```env GANCAO_SCM_EXPRESS_TYPE=sf GANCAO_SCM_CALLBACK_URL=https://... ``` 3. 不要在值周围加引号(除非值本身包含空格) 4. 不要使用 JSON 格式 5. 不要使用数组语法 `[]` ### 步骤 3: 检查配置文件 如果使用了 `config/gancao_scm.php` 配置文件,确保格式正确: ```php env('gancao_scm.enabled', false), 'gateway_url' => env('gancao_scm.gateway_url', ''), 'gateway_ak' => env('gancao_scm.gateway_ak', ''), 'gateway_sk' => env('gancao_scm.gateway_sk', ''), 'biz_ak' => env('gancao_scm.biz_ak', ''), 'biz_sk' => env('gancao_scm.biz_sk', ''), 'callback_url' => env('gancao_scm.callback_url', ''), 'express_type' => env('gancao_scm.express_type', 'sf'), // 确保是字符串 'cradle_store' => env('gancao_scm.cradle_store', ''), 'df_id' => (int)env('gancao_scm.df_id', 101), // 可选配置 'default_is_decoct' => (int)env('gancao_scm.default_is_decoct', 1), 'default_times_per_day' => (int)env('gancao_scm.default_times_per_day', 2), 'default_num_per_pack' => (int)env('gancao_scm.default_num_per_pack', 2), 'default_dose_ml' => (int)env('gancao_scm.default_dose_ml', 150), // 药材 ID 映射(这个可以是数组) 'herb_id_map' => [ // '药材名' => 甘草ID ], ]; ``` ### 步骤 4: 清除缓存 ```bash # 清除 ThinkPHP 缓存 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 # 如果使用 Apache sudo systemctl restart apache2 ``` ### 步骤 6: 查看日志 修复后再次调用接口,查看日志文件: ```bash tail -f server/runtime/log/$(date +%Y%m%d).log ``` 日志会显示: - `Gancao CTM_SUBMIT_RECIPEL payload` - 发送的完整负载 - `Gancao CTM_SUBMIT failed` - 如果通信失败 - `Gancao CTM_SUBMIT api error` - 如果 API 返回错误 - `submitGancaoRecipel exception` - 如果发生异常 ## 代码修复说明 已修复的文件: ### 1. `GancaoScmRecipelService.php` - ✅ 修复 `express_type` 可能是数组的问题 - ✅ 修复 `callback_url` 可能是数组的问题 - ✅ 修复患者年龄格式 - ✅ 优化 `doct_advice` 字段处理 - ✅ 添加调试日志 ### 2. `PrescriptionOrderLogic.php` - ✅ 修复 `$appNo` 变量引用问题 - ✅ 添加详细错误日志 - ✅ 添加异常捕获 ### 3. `PrescriptionOrderController.php` - ✅ 添加 try-catch 异常处理 - ✅ 添加返回值类型检查 - ✅ 添加详细日志记录 ## 测试步骤 1. **运行配置检查**: ```bash php test_gancao_config.php ``` 2. **检查输出**: - 所有配置项应该显示 ✓ - 不应该有 ❌ 或 ⚠️ 标记 - JSON 编码应该成功 3. **调用接口**: ```bash curl -X POST https://your-domain.com/api/tcm.prescriptionOrder/submitGancaoRecipel \ -H "Content-Type: application/json" \ -H "token: your_token" \ -d '{"id": 123}' ``` 4. **查看日志**: ```bash tail -f server/runtime/log/$(date +%Y%m%d).log | grep -i gancao ``` ## 常见错误和解决方案 ### 错误 1: "Array to string conversion" **原因**:配置值是数组而不是字符串 **解决**: 1. 运行 `php test_gancao_config.php` 找出哪个配置是数组 2. 修改 `.env` 文件,移除 `[]` 和引号 3. 清除缓存并重启服务 ### 错误 2: "callback_url is invalid" **原因**:回调地址未配置或格式错误 **解决**: 1. 确保 `GANCAO_SCM_CALLBACK_URL` 配置正确 2. 必须是 HTTPS 地址 3. 格式:`https://your-domain.com/api/gancao/callback` ### 错误 3: "express_type is invalid" **原因**:快递类型配置错误 **解决**: 1. 检查 `GANCAO_SCM_EXPRESS_TYPE` 配置 2. 有效值:`sf`(顺丰)、`jd`(京东)、`jt`(极兔)、`auto`(自动) 3. 默认使用 `sf` ### 错误 4: JSON 编码失败 **原因**:数据中包含无法编码的内容 **解决**: 1. 检查处方数据中是否有特殊字符 2. 检查药材名称是否包含非 UTF-8 字符 3. 查看日志中的完整错误信息 ## 验证修复 修复成功的标志: 1. ✅ 配置检查脚本全部通过 2. ✅ 接口返回成功: ```json { "code": 1, "msg": "甘草药方上传成功", "data": { "recipel_order_no": "GC202604...", "app_order_no": "PO123", "fee": { "total": 150.00, "medicine": 120.00, "process": 20.00, "express": 10.00 } } } ``` 3. ✅ 日志中显示 `submitGancaoRecipel success` 4. ✅ 数据库中 `gancao_reciperl_order_no` 字段已更新 ## 需要帮助? 如果以上步骤都无法解决问题,请提供: 1. 配置检查脚本的完整输出 2. 错误日志的完整内容(`runtime/log/*.log`) 3. 接口返回的完整响应 4. `.env` 文件中的甘草配置部分(隐藏敏感信息) ## 参考文档 - 甘草 API 文档:https://apidoc.igancao.com/service-doc/scm-outer-recipel.html - ThinkPHP 配置文档:https://www.kancloud.cn/manual/thinkphp6_0/1037488