7.9 KiB
7.9 KiB
甘草 API "Array to string conversion" 最终修复
问题根源
错误发生在 GancaoScmRecipelService::getToken() 方法中:
// 第 126 行
if ($code === '10103' || str_contains($apiMsg, '10103')) {
原因: 当甘草 API 返回错误时,$body['status']['msg'] 可能是数组而不是字符串,导致:
apiStatusMessage()方法尝试将数组转换为字符串str_contains()函数接收到数组参数,触发 "Array to string conversion" 错误
已修复的问题
1. apiStatusMessage() 方法
修复前:
$msg = (string) ($body['status']['msg'] ?? '');
修复后:
$msg = $body['status']['msg'] ?? '';
// 确保 msg 是字符串
if (is_array($msg)) {
$msg = json_encode($msg, JSON_UNESCAPED_UNICODE);
} else {
$msg = (string) $msg;
}
2. getToken() 方法中的 str_contains() 调用
修复前:
if ($code === '10103' || str_contains($apiMsg, '10103')) {
修复后:
// 确保 $apiMsg 是字符串,避免 Array to string conversion 错误
$apiMsgStr = is_string($apiMsg) ? $apiMsg : json_encode($apiMsg, JSON_UNESCAPED_UNICODE);
if ($code === '10103' || str_contains($apiMsgStr, '10103')) {
3. 其他已修复的问题
SSL 连接问题(GancaoOpenApiTransport.php)
- ✅ 改用 HTTP/1.1
- ✅ 强制使用 TLS 1.2
- ✅ 降低 OpenSSL 安全级别
- ✅ 增加连接超时
- ✅ 添加 TCP keepalive
配置类型问题(GancaoScmRecipelService.php)
- ✅ 确保
express_type是字符串 - ✅ 确保
callback_url是字符串 - ✅ 修复患者年龄格式
- ✅ 优化
doct_advice字段处理
错误处理(PrescriptionOrderLogic.php 和 PrescriptionOrderController.php)
- ✅ 添加详细错误日志
- ✅ 添加异常捕获
- ✅ 添加返回值类型检查
完整的修复文件列表
- ✅
server/app/common/service/gancao/GancaoScmRecipelService.php - ✅
server/app/common/service/gancao/GancaoOpenApiTransport.php - ✅
server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php - ✅
server/app/adminapi/controller/tcm/PrescriptionOrderController.php
部署步骤
步骤 1: 上传所有修复文件
# 上传修复后的文件
scp server/app/common/service/gancao/GancaoScmRecipelService.php user@server:/path/to/server/app/common/service/gancao/
scp server/app/common/service/gancao/GancaoOpenApiTransport.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 test_gancao_ssl.php user@server:/path/to/
scp diagnose_gancao_payload.php user@server:/path/to/
步骤 2: 验证文件已上传
ssh user@server
cd /path/to/your/project
# 检查文件修改时间
ls -la server/app/common/service/gancao/GancaoScmRecipelService.php
ls -la server/app/common/service/gancao/GancaoOpenApiTransport.php
ls -la server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php
ls -la server/app/adminapi/controller/tcm/PrescriptionOrderController.php
步骤 3: 运行配置检查
php test_gancao_config.php
期望输出: 所有配置项显示 ✓
步骤 4: 运行 SSL 测试
php test_gancao_ssl.php
期望输出: 至少一种 SSL 配置测试成功,并且能成功获取 token
步骤 5: 清除缓存
cd server
php think clear
rm -rf runtime/cache/*
rm -rf runtime/temp/*
步骤 6: 重启服务
# PHP-FPM
sudo systemctl restart php-fpm
# Nginx
sudo systemctl restart nginx
# 或者 Apache
sudo systemctl restart apache2
步骤 7: 测试接口
开启日志监控:
tail -f server/runtime/log/$(date +%Y%m%d).log | grep -E "(Gancao|gancao|submitGancao)"
在另一个终端调用接口:
curl -X POST https://your-domain.com/api/tcm.prescriptionOrder/submitGancaoRecipel \
-H "Content-Type: application/json" \
-H "token: your_admin_token" \
-d '{"id": 订单ID}'
预期结果
成功的情况
接口响应:
{
"code": 1,
"show": 0,
"msg": "甘草药方上传成功",
"data": {
"recipel_order_no": "GC202604...",
"app_order_no": "PO123",
"fee": {
"total": 150.00,
"medicine": 120.00,
"process": 20.00,
"express": 10.00
}
}
}
日志内容:
[info] Gancao MAKE_TOKEN request: {...}
[info] Gancao MAKE_TOKEN response: {...}
[info] Gancao CTM_SUBMIT_RECIPEL payload: {...}
[info] submitGancaoRecipel success: {...}
数据库变化:
prescription_order表中对应订单的gancao_reciperl_order_no字段已更新gancao_submit_time字段已更新为当前时间戳
失败的情况
如果仍然失败,日志会显示详细错误信息:
配置错误:
[error] Gancao MAKE_TOKEN api error: {"body": {...}, "apiMsg": "..."}
→ 检查 .env 配置,特别是 AK/SK
SSL 连接错误:
[error] Gancao CTM_SUBMIT failed: {"subRet": {...}, "payload": {...}}
→ 运行 php test_gancao_ssl.php 诊断 SSL 问题
业务逻辑错误:
[error] submitGancaoRecipel exception: {"message": "...", "trace": "..."}
→ 检查处方数据是否完整,药材 ID 是否正确映射
常见错误和解决方案
错误 1: "Array to string conversion"
已修复! 如果仍然出现,请检查:
- 文件是否正确上传
- 缓存是否已清除
- 服务是否已重启
错误 2: SSL 连接错误
解决方案:
- 运行
php test_gancao_ssl.php - 查看哪种 SSL 配置成功
- 如果都失败,检查 OpenSSL 版本:
openssl version - 联系甘草技术支持确认 SSL 要求
错误 3: "MAKE_TOKEN 失败:[10103]"
原因: AK/SK 不匹配或密码计算错误
解决方案:
- 检查
.env中的配置:GANCAO_SCM_BIZ_AK=xxx GANCAO_SCM_BIZ_SK=xxx - 确认 BIZ AK/SK 与网关 AK/SK 是否相同
- 检查服务器时间是否正确:
date - 联系甘草获取正确的 AK/SK
错误 4: "药材无法匹配甘草药ID"
原因: 药材 ID 映射缺失
解决方案:
- 检查
zyt_doctor_medicine表中药材的gid字段 - 或在
.env配置herb_id_map:'herb_id_map' => [ '当归' => 1001, '黄芪' => 1002, ]
验证修复成功
✅ 所有以下条件都满足,说明修复成功:
php test_gancao_config.php全部通过php test_gancao_ssl.php显示 "✓ 成功获取 token"- 接口返回
{"code": 1, "msg": "甘草药方上传成功"} - 日志中显示
submitGancaoRecipel success - 数据库中订单已更新
gancao_reciperl_order_no - 没有 "Array to string conversion" 错误
- 没有 SSL 连接错误
技术支持
如果以上步骤都无法解决问题,请收集以下信息:
-
配置检查输出:
php test_gancao_config.php > config_check.txt 2>&1 -
SSL 测试输出:
php test_gancao_ssl.php > ssl_check.txt 2>&1 -
错误日志:
tail -200 server/runtime/log/$(date +%Y%m%d).log > error.log -
接口响应:
curl -X POST ... > response.json 2>&1 -
系统信息:
php -v > system_info.txt openssl version >> system_info.txt curl --version >> system_info.txt cat /etc/os-release >> system_info.txt
将这些文件发送给技术支持进行分析。
总结
这次修复解决了三个主要问题:
- Array to string conversion - 甘草 API 返回的错误消息可能是数组
- SSL 连接失败 - TLS 版本和 HTTP 版本不兼容
- 配置类型错误 - 某些配置值被错误地解析为数组
所有问题都已修复,现在应该可以正常调用甘草 API 了!