5.3 KiB
5.3 KiB
甘草 API "Array to string conversion" 错误修复
问题描述
调用甘草处方下单接口时出现错误:
{"code":2,"message":"Array to string conversion"}
根本原因
经过分析代码和 API 文档,发现以下几个问题:
1. 变量作用域问题
在 PrescriptionOrderLogic::submitGancaoRecipel() 方法中,$appNo 变量在返回语句中被引用,但实际定义在更早的位置(line 1638),然后又在 line 1658 被重新赋值。这可能导致变量引用错误。
2. 空字符串处理问题
buildSubmitPayload() 方法中的 cradle_store 字段可能为空字符串,而甘草 API 可能不接受空字符串。
3. 患者年龄格式问题
原代码使用 sprintf('%d.00', $ageInt) 格式化年龄,但 API 可能期望简单的整数字符串。
4. doct_advice 字段处理
doct_advice 数组中的某些字段可能包含空字符串或未正确处理的值,导致 JSON 编码时出现问题。
修复内容
1. 修复 GancaoScmRecipelService.php
修改患者年龄格式
// 修改前
$patientAge = sprintf('%d.00', $ageInt);
// 修改后
$patientAge = (string) $ageInt;
确保 cradle_store 不为空
$preview['cradle_store'] = mb_substr(trim((string) ($c['cradle_store'] ?? '')), 0, 32);
if ($preview['cradle_store'] === '') {
$preview['cradle_store'] = 'default';
}
优化 doct_advice 字段处理
// 确保所有字段都是字符串,避免数组到字符串的转换错误
$tabooStr = $taboo !== '' ? $taboo : '无';
$usageTimeStr = $usageTime;
$usageBriefStr = $usageBrief !== '' ? $usageBrief : '遵医嘱';
$othersStr = trim((string) ($rx['usage_notes'] ?? ''));
$notesDoctorStr = trim((string) ($order['remark_extra'] ?? ''));
$preview['doct_advice'] = [
'taboo' => $tabooStr,
'usage_time' => $usageTimeStr,
'usage_brief' => $usageBriefStr,
'others' => $othersStr !== '' ? $othersStr : '',
'notes_doctor' => $notesDoctorStr !== '' ? $notesDoctorStr : '',
];
添加调试日志
public static function ctmSubmit(array $submitPayload): array
{
$transport = self::transport();
// 记录请求负载以便调试
Log::info('Gancao CTM_SUBMIT_RECIPEL payload', ['payload' => $submitPayload]);
return $transport->post($submitPayload);
}
2. 修复 PrescriptionOrderLogic.php
修复变量引用问题
// 在返回语句中使用正确的变量引用
$fee = $subBody['result']['fee'] ?? [];
$appNo = $submitPayload['app_order_no'] ?? ('PO' . (string) $order->id);
return [
'recipel_order_no' => $gcNo,
'app_order_no' => $appNo,
'fee' => is_array($fee) ? $fee : [],
];
添加详细错误日志
use think\facade\Log;
// 在 submitGancaoRecipel 方法中添加错误日志
$subRet = GancaoScmRecipelService::ctmSubmit($submitPayload);
if ((int) ($subRet['state'] ?? 0) !== 1) {
$errMsg = (string) ($subRet['msg'] ?? '');
$response = isset($subRet['response']) ? mb_substr((string) $subRet['response'], 0, 500) : '';
self::$error = '甘草下单通信失败:' . $errMsg . ($response !== '' ? ';响应:' . $response : '');
Log::error('Gancao CTM_SUBMIT failed', ['subRet' => $subRet, 'payload' => $submitPayload]);
return false;
}
$subBody = $subRet['body'] ?? [];
if (!GancaoScmRecipelService::isApiSuccess($subBody)) {
self::$error = '甘草下单失败:' . GancaoScmRecipelService::apiStatusMessage($subBody);
Log::error('Gancao CTM_SUBMIT api error', ['body' => $subBody, 'payload' => $submitPayload]);
return false;
}
测试建议
-
检查日志文件:修复后再次调用接口,查看
runtime/log/目录下的日志文件,查找Gancao CTM_SUBMIT_RECIPEL payload日志,确认发送的数据格式是否正确。 -
验证必填字段:根据甘草 API 文档,确保以下字段都有有效值:
token:有效的 API tokendf_id:剂型 ID(如 101 表示饮片)amount:剂量数量m_list:药材列表(每个药材必须有id、quantity、brief字段)express_to:收货地址信息patient:患者信息doctor:医生信息callback_url:回调地址(必须是 HTTPS)
-
检查配置:确认
.env文件中的甘草配置完整:GANCAO_SCM_ENABLED=true GANCAO_SCM_GATEWAY_URL=https://xxx GANCAO_SCM_GATEWAY_AK=xxx GANCAO_SCM_GATEWAY_SK=xxx GANCAO_SCM_BIZ_AK=xxx GANCAO_SCM_BIZ_SK=xxx GANCAO_SCM_CALLBACK_URL=https://xxx GANCAO_SCM_CRADLE_STORE=xxx GANCAO_SCM_EXPRESS_TYPE=sf -
测试流程:
- 创建一个测试处方订单
- 确保处方审核通过
- 调用
submitGancaoRecipel接口 - 查看返回结果和日志
可能的其他原因
如果修复后仍然出现错误,可能是以下原因:
- 药材 ID 映射问题:某些药材的甘草 ID(
gid)未正确配置 - 剂型参数问题:
df101ext等剂型扩展参数不符合 API 要求 - 地址解析问题:收货地址无法正确解析为省市区
- 电话号码格式:电话号码不是 11 位数字
参考文档
- 甘草 API 文档:https://apidoc.igancao.com/service-doc/scm-outer-recipel.html
- 特别关注「中药处方下单」和「中药处方下单参数预检查」章节