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

319 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 甘草 API "Array to string conversion" 最终修复
## 问题根源
错误发生在 `GancaoScmRecipelService::getToken()` 方法中:
```php
// 第 126 行
if ($code === '10103' || str_contains($apiMsg, '10103')) {
```
**原因:** 当甘草 API 返回错误时,`$body['status']['msg']` 可能是**数组**而不是字符串,导致:
1. `apiStatusMessage()` 方法尝试将数组转换为字符串
2. `str_contains()` 函数接收到数组参数,触发 "Array to string conversion" 错误
## 已修复的问题
### 1. `apiStatusMessage()` 方法
**修复前:**
```php
$msg = (string) ($body['status']['msg'] ?? '');
```
**修复后:**
```php
$msg = $body['status']['msg'] ?? '';
// 确保 msg 是字符串
if (is_array($msg)) {
$msg = json_encode($msg, JSON_UNESCAPED_UNICODE);
} else {
$msg = (string) $msg;
}
```
### 2. `getToken()` 方法中的 `str_contains()` 调用
**修复前:**
```php
if ($code === '10103' || str_contains($apiMsg, '10103')) {
```
**修复后:**
```php
// 确保 $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`
- ✅ 添加详细错误日志
- ✅ 添加异常捕获
- ✅ 添加返回值类型检查
## 完整的修复文件列表
1.`server/app/common/service/gancao/GancaoScmRecipelService.php`
2.`server/app/common/service/gancao/GancaoOpenApiTransport.php`
3.`server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php`
4.`server/app/adminapi/controller/tcm/PrescriptionOrderController.php`
## 部署步骤
### 步骤 1: 上传所有修复文件
```bash
# 上传修复后的文件
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: 验证文件已上传
```bash
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: 运行配置检查
```bash
php test_gancao_config.php
```
**期望输出:** 所有配置项显示 ✓
### 步骤 4: 运行 SSL 测试
```bash
php test_gancao_ssl.php
```
**期望输出:** 至少一种 SSL 配置测试成功,并且能成功获取 token
### 步骤 5: 清除缓存
```bash
cd server
php think clear
rm -rf runtime/cache/*
rm -rf runtime/temp/*
```
### 步骤 6: 重启服务
```bash
# PHP-FPM
sudo systemctl restart php-fpm
# Nginx
sudo systemctl restart nginx
# 或者 Apache
sudo systemctl restart apache2
```
### 步骤 7: 测试接口
**开启日志监控:**
```bash
tail -f server/runtime/log/$(date +%Y%m%d).log | grep -E "(Gancao|gancao|submitGancao)"
```
**在另一个终端调用接口:**
```bash
curl -X POST https://your-domain.com/api/tcm.prescriptionOrder/submitGancaoRecipel \
-H "Content-Type: application/json" \
-H "token: your_admin_token" \
-d '{"id": 订单ID}'
```
## 预期结果
### 成功的情况
**接口响应:**
```json
{
"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"
**已修复!** 如果仍然出现,请检查:
1. 文件是否正确上传
2. 缓存是否已清除
3. 服务是否已重启
### 错误 2: SSL 连接错误
**解决方案:**
1. 运行 `php test_gancao_ssl.php`
2. 查看哪种 SSL 配置成功
3. 如果都失败,检查 OpenSSL 版本:`openssl version`
4. 联系甘草技术支持确认 SSL 要求
### 错误 3: "MAKE_TOKEN 失败:[10103]"
**原因:** AK/SK 不匹配或密码计算错误
**解决方案:**
1. 检查 `.env` 中的配置:
```env
GANCAO_SCM_BIZ_AK=xxx
GANCAO_SCM_BIZ_SK=xxx
```
2. 确认 BIZ AK/SK 与网关 AK/SK 是否相同
3. 检查服务器时间是否正确:`date`
4. 联系甘草获取正确的 AK/SK
### 错误 4: "药材无法匹配甘草药ID"
**原因:** 药材 ID 映射缺失
**解决方案:**
1. 检查 `zyt_doctor_medicine` 表中药材的 `gid` 字段
2. 或在 `.env` 配置 `herb_id_map`
```php
'herb_id_map' => [
'当归' => 1001,
'黄芪' => 1002,
]
```
## 验证修复成功
✅ **所有以下条件都满足,说明修复成功:**
1. `php test_gancao_config.php` 全部通过
2. `php test_gancao_ssl.php` 显示 "✓ 成功获取 token"
3. 接口返回 `{"code": 1, "msg": "甘草药方上传成功"}`
4. 日志中显示 `submitGancaoRecipel success`
5. 数据库中订单已更新 `gancao_reciperl_order_no`
6. 没有 "Array to string conversion" 错误
7. 没有 SSL 连接错误
## 技术支持
如果以上步骤都无法解决问题,请收集以下信息:
1. **配置检查输出:**
```bash
php test_gancao_config.php > config_check.txt 2>&1
```
2. **SSL 测试输出:**
```bash
php test_gancao_ssl.php > ssl_check.txt 2>&1
```
3. **错误日志:**
```bash
tail -200 server/runtime/log/$(date +%Y%m%d).log > error.log
```
4. **接口响应:**
```bash
curl -X POST ... > response.json 2>&1
```
5. **系统信息:**
```bash
php -v > system_info.txt
openssl version >> system_info.txt
curl --version >> system_info.txt
cat /etc/os-release >> system_info.txt
```
将这些文件发送给技术支持进行分析。
## 总结
这次修复解决了三个主要问题:
1. **Array to string conversion** - 甘草 API 返回的错误消息可能是数组
2. **SSL 连接失败** - TLS 版本和 HTTP 版本不兼容
3. **配置类型错误** - 某些配置值被错误地解析为数组
所有问题都已修复,现在应该可以正常调用甘草 API 了!