162 lines
5.3 KiB
Markdown
162 lines
5.3 KiB
Markdown
# 甘草 API "Array to string conversion" 错误修复
|
||
|
||
## 问题描述
|
||
|
||
调用甘草处方下单接口时出现错误:
|
||
```json
|
||
{"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`
|
||
|
||
#### 修改患者年龄格式
|
||
```php
|
||
// 修改前
|
||
$patientAge = sprintf('%d.00', $ageInt);
|
||
|
||
// 修改后
|
||
$patientAge = (string) $ageInt;
|
||
```
|
||
|
||
#### 确保 cradle_store 不为空
|
||
```php
|
||
$preview['cradle_store'] = mb_substr(trim((string) ($c['cradle_store'] ?? '')), 0, 32);
|
||
if ($preview['cradle_store'] === '') {
|
||
$preview['cradle_store'] = 'default';
|
||
}
|
||
```
|
||
|
||
#### 优化 doct_advice 字段处理
|
||
```php
|
||
// 确保所有字段都是字符串,避免数组到字符串的转换错误
|
||
$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 : '',
|
||
];
|
||
```
|
||
|
||
#### 添加调试日志
|
||
```php
|
||
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`
|
||
|
||
#### 修复变量引用问题
|
||
```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 : [],
|
||
];
|
||
```
|
||
|
||
#### 添加详细错误日志
|
||
```php
|
||
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`:药材列表(每个药材必须有 `id`、`quantity`、`brief` 字段)
|
||
- `express_to`:收货地址信息
|
||
- `patient`:患者信息
|
||
- `doctor`:医生信息
|
||
- `callback_url`:回调地址(必须是 HTTPS)
|
||
|
||
3. **检查配置**:确认 `.env` 文件中的甘草配置完整:
|
||
```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 映射问题**:某些药材的甘草 ID(`gid`)未正确配置
|
||
2. **剂型参数问题**:`df101ext` 等剂型扩展参数不符合 API 要求
|
||
3. **地址解析问题**:收货地址无法正确解析为省市区
|
||
4. **电话号码格式**:电话号码不是 11 位数字
|
||
|
||
## 参考文档
|
||
|
||
- 甘草 API 文档:https://apidoc.igancao.com/service-doc/scm-outer-recipel.html
|
||
- 特别关注「中药处方下单」和「中药处方下单参数预检查」章节
|