更新
This commit is contained in:
@@ -18,6 +18,7 @@ use think\console\Output;
|
|||||||
* 数据流:
|
* 数据流:
|
||||||
* zyt_tcm_prescription_order (甘草已上传)
|
* zyt_tcm_prescription_order (甘草已上传)
|
||||||
* ↓ 调用 igc_scm.logistics.client_opt.pull / GET_TASK_ROUTE_LIST
|
* ↓ 调用 igc_scm.logistics.client_opt.pull / GET_TASK_ROUTE_LIST
|
||||||
|
* ↓ 甘草报快递任务不存在等(如 10101)且业务单已有运单号 → 降级快递100
|
||||||
* zyt_express_tracking + zyt_express_trace + zyt_express_state_log + zyt_express_query_log
|
* zyt_express_tracking + zyt_express_trace + zyt_express_state_log + zyt_express_query_log
|
||||||
*
|
*
|
||||||
* 使用方法:
|
* 使用方法:
|
||||||
|
|||||||
@@ -162,6 +162,76 @@ class ExpressTrackingService
|
|||||||
return $stats;
|
return $stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘草路由不可用时的降级:按业务订单运单号走快递100 查询并落库(自发货等场景)
|
||||||
|
*
|
||||||
|
* @return array{
|
||||||
|
* success: bool,
|
||||||
|
* message: string,
|
||||||
|
* traces_count: int,
|
||||||
|
* state: string,
|
||||||
|
* source: string,
|
||||||
|
* assistant_sync?: array|null
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public static function queryKuaidiForPrescriptionOrder(PrescriptionOrder $order, bool $isAuto = true): array
|
||||||
|
{
|
||||||
|
$fail = static fn (string $msg): array => [
|
||||||
|
'success' => false,
|
||||||
|
'message' => $msg,
|
||||||
|
'traces_count' => 0,
|
||||||
|
'state' => '',
|
||||||
|
'source' => 'kuaidi100_fallback',
|
||||||
|
'assistant_sync' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
$tn = trim((string) ($order->tracking_number ?? ''));
|
||||||
|
if ($tn === '') {
|
||||||
|
return $fail('甘草无快递任务且业务单未填写快递单号,无法走快递100');
|
||||||
|
}
|
||||||
|
|
||||||
|
$tracking = self::resolveTrackingByNumber($tn);
|
||||||
|
if (!$tracking) {
|
||||||
|
return $fail('未找到运单对应的物流追踪记录');
|
||||||
|
}
|
||||||
|
|
||||||
|
self::backfillRecipientPhoneFromPrescriptionOrder($tracking);
|
||||||
|
self::syncTrackingExpressCompanyFromNumber($tracking);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = self::queryAndUpdate((int) $tracking->id, $isAuto);
|
||||||
|
$ok = self::isKuaidiQuerySuccessful($result);
|
||||||
|
$tracking = ExpressTracking::where('id', (int) $tracking->id)->whereNull('delete_time')->find();
|
||||||
|
$state = $tracking ? (string) ($tracking->current_state ?? '') : '';
|
||||||
|
$hint = trim((string) ($result['hint'] ?? ''));
|
||||||
|
$message = $ok
|
||||||
|
? 'ok(甘草无快递任务,已降级快递100)'
|
||||||
|
: ($hint !== '' ? $hint : '快递100 查询未返回有效轨迹');
|
||||||
|
|
||||||
|
$assistantSync = null;
|
||||||
|
if (is_array($result) && isset($result['_assistant_sync']) && is_array($result['_assistant_sync'])) {
|
||||||
|
$assistantSync = $result['_assistant_sync'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => $ok,
|
||||||
|
'message' => $message,
|
||||||
|
'traces_count' => count($result['traces'] ?? []),
|
||||||
|
'state' => $state,
|
||||||
|
'source' => 'kuaidi100_fallback',
|
||||||
|
'assistant_sync' => $assistantSync,
|
||||||
|
];
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::error('queryKuaidiForPrescriptionOrder failed', [
|
||||||
|
'order_id' => (int) $order->id,
|
||||||
|
'tracking_number' => $tn,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $fail('快递100 降级异常:' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确保 express_tracking 存在(不发起查询)
|
* 确保 express_tracking 存在(不发起查询)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -69,7 +69,11 @@ final class GancaoLogisticsRouteService
|
|||||||
|
|
||||||
$resp = self::callRouteApi($appOrderNo);
|
$resp = self::callRouteApi($appOrderNo);
|
||||||
if (!$resp['success']) {
|
if (!$resp['success']) {
|
||||||
self::logQuery($order, '', 'auto', false, 0, $resp['message']);
|
self::logQuery($order, '', 'auto', false, (int) ($resp['runtime_ms'] ?? 0), $resp['message']);
|
||||||
|
if (self::shouldFallbackToKuaidi100($resp)) {
|
||||||
|
return self::syncOneViaKuaidi100($order, (string) $resp['message']);
|
||||||
|
}
|
||||||
|
|
||||||
return ['success' => false, 'message' => $resp['message'], 'traces_count' => 0, 'state' => ''];
|
return ['success' => false, 'message' => $resp['message'], 'traces_count' => 0, 'state' => ''];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +91,10 @@ final class GancaoLogisticsRouteService
|
|||||||
|
|
||||||
if ($trackingNumber === '') {
|
if ($trackingNumber === '') {
|
||||||
self::logQuery($order, '', 'auto', false, $resp['runtime_ms'], '甘草未返回 sp_order_no(快递单号),可能尚未发货');
|
self::logQuery($order, '', 'auto', false, $resp['runtime_ms'], '甘草未返回 sp_order_no(快递单号),可能尚未发货');
|
||||||
|
if (trim((string) ($order->tracking_number ?? '')) !== '') {
|
||||||
|
return self::syncOneViaKuaidi100($order, '甘草未返回快递单号,业务单已填写运单号');
|
||||||
|
}
|
||||||
|
|
||||||
return ['success' => false, 'message' => '尚未发货(无快递单号)', 'traces_count' => 0, 'state' => ''];
|
return ['success' => false, 'message' => '尚未发货(无快递单号)', 'traces_count' => 0, 'state' => ''];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,11 +144,54 @@ final class GancaoLogisticsRouteService
|
|||||||
'message' => 'ok',
|
'message' => 'ok',
|
||||||
'traces_count' => $tracesCount,
|
'traces_count' => $tracesCount,
|
||||||
'state' => $newState,
|
'state' => $newState,
|
||||||
|
'source' => 'gancao',
|
||||||
'raw' => $result,
|
'raw' => $result,
|
||||||
'assistant_sync' => $assistantSync,
|
'assistant_sync' => $assistantSync,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘草侧无快递任务 / 路由拉取失败时,按业务单运单号降级快递100(自发货)
|
||||||
|
*
|
||||||
|
* @return array{success:bool, message:string, traces_count:int, state:string, source?:string, assistant_sync?:array|null}
|
||||||
|
*/
|
||||||
|
private static function syncOneViaKuaidi100(PrescriptionOrder $order, string $gancaoReason): array
|
||||||
|
{
|
||||||
|
$ret = ExpressTrackingService::queryKuaidiForPrescriptionOrder($order, true);
|
||||||
|
if (!$ret['success']) {
|
||||||
|
$ret['message'] = trim((string) $ret['message']) . ';甘草:' . mb_substr($gancaoReason, 0, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否因甘草「快递任务」类错误降级走快递100
|
||||||
|
*
|
||||||
|
* @param array{success?:bool, message?:string, api_code?:string} $gancaoResp
|
||||||
|
*/
|
||||||
|
private static function shouldFallbackToKuaidi100(array $gancaoResp): bool
|
||||||
|
{
|
||||||
|
$code = trim((string) ($gancaoResp['api_code'] ?? ''));
|
||||||
|
if ($code === '10101') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$msg = (string) ($gancaoResp['message'] ?? '');
|
||||||
|
if ($msg === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$needles = ['快递任务', '任务id不存在', '任务不存在', '无快递任务', '物流任务'];
|
||||||
|
foreach ($needles as $needle) {
|
||||||
|
if (mb_strpos($msg, $needle) !== false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用甘草 GET_TASK_ROUTE_LIST 接口
|
* 调用甘草 GET_TASK_ROUTE_LIST 接口
|
||||||
*
|
*
|
||||||
@@ -181,6 +232,7 @@ final class GancaoLogisticsRouteService
|
|||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'API 错误:' . GancaoScmRecipelService::apiStatusMessage($body),
|
'message' => 'API 错误:' . GancaoScmRecipelService::apiStatusMessage($body),
|
||||||
|
'api_code' => (string) ($body['status']['code'] ?? ''),
|
||||||
'runtime_ms' => $runtimeMs,
|
'runtime_ms' => $runtimeMs,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -499,6 +551,7 @@ final class GancaoLogisticsRouteService
|
|||||||
'message' => $r['message'],
|
'message' => $r['message'],
|
||||||
'traces' => $r['traces_count'],
|
'traces' => $r['traces_count'],
|
||||||
'state' => $r['state'],
|
'state' => $r['state'],
|
||||||
|
'source' => $r['source'] ?? 'gancao',
|
||||||
];
|
];
|
||||||
if ($r['success']) {
|
if ($r['success']) {
|
||||||
$stats['success']++;
|
$stats['success']++;
|
||||||
@@ -507,8 +560,10 @@ final class GancaoLogisticsRouteService
|
|||||||
$act = (string) ($sync['action'] ?? '');
|
$act = (string) ($sync['action'] ?? '');
|
||||||
if ($act === 'cleared') {
|
if ($act === 'cleared') {
|
||||||
$stats['assistant_cleared']++;
|
$stats['assistant_cleared']++;
|
||||||
|
$channel = (($r['source'] ?? '') === 'kuaidi100_fallback') ? '快递100降级' : '甘草路由';
|
||||||
$stats['assistant_lines'][] = sprintf(
|
$stats['assistant_lines'][] = sprintf(
|
||||||
'[移除医助+指派日志][甘草路由] 诊单=%d 业务订单=%d 运单=%s 原医助ID=%s 履约状态=%d',
|
'[移除医助+指派日志][%s] 诊单=%d 业务订单=%d 运单=%s 原医助ID=%s 履约状态=%d',
|
||||||
|
$channel,
|
||||||
(int) ($sync['diagnosis_id'] ?? 0),
|
(int) ($sync['diagnosis_id'] ?? 0),
|
||||||
(int) ($sync['prescription_order_id'] ?? 0),
|
(int) ($sync['prescription_order_id'] ?? 0),
|
||||||
(string) ($sync['tracking_number'] ?? ''),
|
(string) ($sync['tracking_number'] ?? ''),
|
||||||
|
|||||||
Reference in New Issue
Block a user