This commit is contained in:
Your Name
2026-04-30 17:36:47 +08:00
parent 4c21ee5938
commit 7e557b1ea2
33 changed files with 8718 additions and 94 deletions
@@ -8,6 +8,8 @@ use app\common\model\ExpressTracking;
use app\common\model\ExpressTrace;
use app\common\model\ExpressStateLog;
use app\common\model\ExpressQueryLog;
use app\common\model\tcm\Diagnosis;
use app\common\model\tcm\DiagnosisAssignLog;
use app\common\model\tcm\PrescriptionOrder;
use app\common\model\tcm\PrescriptionOrderLog;
use think\facade\Log;
@@ -76,7 +78,7 @@ class ExpressTrackingService
*
* @param int $trackingId
* @param bool $isAuto 是否自动查询
* @return array|null
* @return array<string, mixed>|null 快递100 查询结果;自动任务时可能含 _assistant_sync(医助移除/跳过)
*/
public static function queryAndUpdate(int $trackingId, bool $isAuto = false): ?array
{
@@ -174,7 +176,13 @@ class ExpressTrackingService
self::logStateChange($tracking, $oldState);
}
return $result;
// 定时拉轨迹:业务订单已发货时释放诊单医助(有正式指派记录则跳过,与结案逻辑一致)
$assistantSync = null;
if ($isAuto) {
$assistantSync = self::maybeClearDiagnosisAssistantWhenShippedPrescription($tracking);
}
return $assistantSync !== null ? array_merge($result, ['_assistant_sync' => $assistantSync]) : $result;
}
/**
@@ -233,6 +241,147 @@ class ExpressTrackingService
}
}
/**
* 业务订单已发货(5)/已签收(6)时清空关联诊单医助;存在 tcm_diagnosis_assign_log 则跳过。
* 供 express:auto-update、gancao:sync-logistics、甘草回调等共用。
*
* @param array{tracking_id?:int,tracking_number?:string,source?:string} $meta
* @return array{
* action: 'cleared'|'skipped_assign_log',
* source?: string,
* diagnosis_id: int,
* prescription_order_id: int,
* tracking_id: int,
* tracking_number: string,
* former_assistant_id?: string,
* assistant_id?: string,
* assign_log_count?: int,
* fulfillment_status?: int
* }|null
*/
public static function applyAssistantReleaseForShippedPrescriptionOrder(PrescriptionOrder $order, array $meta = []): ?array
{
$orderId = (int) $order->id;
if ($orderId <= 0) {
return null;
}
$source = (string) ($meta['source'] ?? '');
$trackingId = (int) ($meta['tracking_id'] ?? 0);
$tn = (string) ($meta['tracking_number'] ?? $order->tracking_number ?? '');
try {
$fs = (int) $order->fulfillment_status;
if (!in_array($fs, [5, 6], true)) {
return null;
}
$diagnosisId = (int) ($order->diagnosis_id ?? 0);
if ($diagnosisId <= 0) {
return null;
}
$diag = Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->find();
if (!$diag) {
return null;
}
$oldAssistant = (string) ($diag->getAttr('assistant_id') ?? '');
if ($oldAssistant === '' || $oldAssistant === '0') {
return null;
}
$assignLogCount = (int) DiagnosisAssignLog::where('diagnosis_id', $diagnosisId)
->whereNull('delete_time')
->count();
if ($assignLogCount > 0) {
return [
'action' => 'skipped_assign_log',
'source' => $source,
'diagnosis_id' => $diagnosisId,
'prescription_order_id' => $orderId,
'tracking_id' => $trackingId,
'tracking_number' => $tn,
'assistant_id' => $oldAssistant,
'assign_log_count' => $assignLogCount,
'fulfillment_status' => $fs,
];
}
Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->update(['assistant_id' => '']);
Log::info('Cleared diagnosis assistant (shipped/signed prescription order)', [
'source' => $source,
'diagnosis_id' => $diagnosisId,
'prescription_order_id' => $orderId,
'tracking_id' => $trackingId,
'fulfillment_status' => $fs,
'former_assistant_id' => $oldAssistant,
]);
return [
'action' => 'cleared',
'source' => $source,
'diagnosis_id' => $diagnosisId,
'prescription_order_id' => $orderId,
'tracking_id' => $trackingId,
'tracking_number' => $tn,
'former_assistant_id' => $oldAssistant,
'fulfillment_status' => $fs,
];
} catch (\Throwable $e) {
Log::warning('applyAssistantReleaseForShippedPrescriptionOrder failed: ' . $e->getMessage(), [
'source' => $source,
'order_id' => $orderId,
]);
return null;
}
}
/**
* @return array{
* action: 'cleared'|'skipped_assign_log',
* source?: string,
* diagnosis_id: int,
* prescription_order_id: int,
* tracking_id: int,
* tracking_number: string,
* former_assistant_id?: string,
* assistant_id?: string,
* assign_log_count?: int,
* fulfillment_status?: int
* }|null
*/
private static function maybeClearDiagnosisAssistantWhenShippedPrescription(ExpressTracking $tracking): ?array
{
if ((string) $tracking->order_type !== 'prescription') {
return null;
}
$orderId = (int) $tracking->order_id;
if ($orderId <= 0) {
return null;
}
try {
$order = PrescriptionOrder::where('id', $orderId)->whereNull('delete_time')->find();
if (!$order) {
return null;
}
return self::applyAssistantReleaseForShippedPrescriptionOrder($order, [
'tracking_id' => (int) $tracking->id,
'tracking_number' => (string) $tracking->tracking_number,
'source' => 'express_auto_update',
]);
} catch (\Throwable $e) {
Log::warning('maybeClearDiagnosisAssistantWhenShippedPrescription failed: ' . $e->getMessage(), [
'tracking_id' => (int) $tracking->id,
'order_id' => $orderId,
]);
return null;
}
}
/**
* 物流表未存收件人手机时,从关联业务订单回填(顺丰/京东等查件必填后四位)
*/
@@ -383,7 +532,14 @@ class ExpressTrackingService
* 批量自动更新(定时任务调用)
*
* @param int $limit 每次处理数量
* @return array
* @return array{
* total: int,
* success: int,
* failed: int,
* assistant_cleared: int,
* assistant_skipped_assign_log: int,
* assistant_lines: list<string>
* }
*/
public static function autoUpdateBatch(int $limit = 50): array
{
@@ -423,11 +579,40 @@ class ExpressTrackingService
$success = 0;
$failed = 0;
$assistantCleared = 0;
$assistantSkippedAssign = 0;
$assistantLines = [];
foreach ($list as $tracking) {
try {
self::queryAndUpdate($tracking->id, true);
$ret = self::queryAndUpdate($tracking->id, true);
$success++;
if (is_array($ret) && isset($ret['_assistant_sync']) && is_array($ret['_assistant_sync'])) {
$sync = $ret['_assistant_sync'];
$act = (string) ($sync['action'] ?? '');
if ($act === 'cleared') {
$assistantCleared++;
$assistantLines[] = sprintf(
'[移除医助] 诊单=%d 业务订单=%d 运单=%s 原医助ID=%s 履约状态=%d',
(int) ($sync['diagnosis_id'] ?? 0),
(int) ($sync['prescription_order_id'] ?? 0),
(string) ($sync['tracking_number'] ?? ''),
(string) ($sync['former_assistant_id'] ?? ''),
(int) ($sync['fulfillment_status'] ?? 0)
);
} elseif ($act === 'skipped_assign_log') {
$assistantSkippedAssign++;
$assistantLines[] = sprintf(
'[保留医助] 诊单=%d 业务订单=%d 运单=%s 医助ID=%s 指派记录=%d条 履约状态=%d',
(int) ($sync['diagnosis_id'] ?? 0),
(int) ($sync['prescription_order_id'] ?? 0),
(string) ($sync['tracking_number'] ?? ''),
(string) ($sync['assistant_id'] ?? ''),
(int) ($sync['assign_log_count'] ?? 0),
(int) ($sync['fulfillment_status'] ?? 0)
);
}
}
} catch (\Throwable $e) {
$failed++;
Log::error('Auto update express tracking failed', [
@@ -442,6 +627,9 @@ class ExpressTrackingService
'total' => count($list),
'success' => $success,
'failed' => $failed,
'assistant_cleared' => $assistantCleared,
'assistant_skipped_assign_log' => $assistantSkippedAssign,
'assistant_lines' => $assistantLines,
];
}