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

5.3 KiB
Raw Blame History

甘草 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;
}

测试建议

  1. 检查日志文件:修复后再次调用接口,查看 runtime/log/ 目录下的日志文件,查找 Gancao CTM_SUBMIT_RECIPEL payload 日志,确认发送的数据格式是否正确。

  2. 验证必填字段:根据甘草 API 文档,确保以下字段都有有效值:

    • token:有效的 API token
    • df_id:剂型 ID(如 101 表示饮片)
    • amount:剂量数量
    • m_list:药材列表(每个药材必须有 idquantitybrief 字段)
    • express_to:收货地址信息
    • patient:患者信息
    • doctor:医生信息
    • callback_url:回调地址(必须是 HTTPS
  3. 检查配置:确认 .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
    
  4. 测试流程

    • 创建一个测试处方订单
    • 确保处方审核通过
    • 调用 submitGancaoRecipel 接口
    • 查看返回结果和日志

可能的其他原因

如果修复后仍然出现错误,可能是以下原因:

  1. 药材 ID 映射问题:某些药材的甘草 IDgid)未正确配置
  2. 剂型参数问题df101ext 等剂型扩展参数不符合 API 要求
  3. 地址解析问题:收货地址无法正确解析为省市区
  4. 电话号码格式:电话号码不是 11 位数字

参考文档