更新
This commit is contained in:
@@ -12,6 +12,7 @@ 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\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
@@ -176,7 +177,7 @@ class ExpressTrackingService
|
||||
self::logStateChange($tracking, $oldState);
|
||||
}
|
||||
|
||||
// 定时拉轨迹:业务订单已发货时释放诊单医助(有正式指派记录则跳过,与结案逻辑一致)
|
||||
// 定时拉轨迹:履约已发货/已签收时与甘草侧共用 applyAssistantReleaseForShippedPrescriptionOrder,释放诊单医助并写指派日志
|
||||
$assistantSync = null;
|
||||
if ($isAuto) {
|
||||
$assistantSync = self::maybeClearDiagnosisAssistantWhenShippedPrescription($tracking);
|
||||
@@ -242,20 +243,19 @@ class ExpressTrackingService
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务订单已发货(5)/已签收(6)时清空关联诊单医助;存在 tcm_diagnosis_assign_log 则跳过。
|
||||
* 供 express:auto-update、gancao:sync-logistics、甘草回调等共用。
|
||||
* 处方业务订单履约「已发货(5) / 已签收(6)」时:清空关联诊单(患者)医助,并写入 tcm_diagnosis_assign_log。
|
||||
* 快递 100 定时拉轨迹、甘草路由、甘草回调与履约核对共用同一规则。
|
||||
* 例外:指派日志中若存在「从某医助改派到另一医助」(原、新医助 ID 均大于 0)的记录,视为人工指派链,自动释放跳过。
|
||||
*
|
||||
* @param array{tracking_id?:int,tracking_number?:string,source?:string} $meta
|
||||
* @return array{
|
||||
* action: 'cleared'|'skipped_assign_log',
|
||||
* action: 'cleared',
|
||||
* 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
|
||||
*/
|
||||
@@ -284,52 +284,73 @@ class ExpressTrackingService
|
||||
if (!$diag) {
|
||||
return null;
|
||||
}
|
||||
$oldAssistant = (string) ($diag->getAttr('assistant_id') ?? '');
|
||||
if ($oldAssistant === '' || $oldAssistant === '0') {
|
||||
$fromAssistantId = (int) ($diag->getAttr('assistant_id') ?? 0);
|
||||
if ($fromAssistantId <= 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,
|
||||
if (self::diagnosisHasFormalAssistantReassignInAssignLog($diagnosisId)) {
|
||||
Log::info('Skipped auto assistant release (shipped/signed): formal assistant reassign in assign log', [
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'prescription_order_id' => $orderId,
|
||||
'tracking_id' => $trackingId,
|
||||
'tracking_number' => $tn,
|
||||
'assistant_id' => $oldAssistant,
|
||||
'assign_log_count' => $assignLogCount,
|
||||
'fulfillment_status' => $fs,
|
||||
];
|
||||
'source' => $source,
|
||||
'current_assistant_id' => $fromAssistantId,
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->update(['assistant_id' => '']);
|
||||
$operatorName = match ($source) {
|
||||
'express_auto_update' => '系统·物流自动同步',
|
||||
'gancao_route', 'gancao_route_sync' => '系统·甘草路由同步',
|
||||
'gancao_callback' => '系统·甘草回调',
|
||||
'shipped_fulfillment_reconcile' => '系统·已发货履约核对',
|
||||
default => '系统·订单已发货/签收',
|
||||
};
|
||||
|
||||
Log::info('Cleared diagnosis assistant (shipped/signed prescription order)', [
|
||||
'source' => $source,
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
Db::startTrans();
|
||||
try {
|
||||
Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->update(['assistant_id' => 0]);
|
||||
|
||||
DiagnosisAssignLog::create([
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'from_assistant_id' => $fromAssistantId,
|
||||
'to_assistant_id' => 0,
|
||||
'operator_admin_id' => 0,
|
||||
'operator_name' => $operatorName,
|
||||
'operator_account' => '',
|
||||
'ip' => '',
|
||||
'create_time' => time(),
|
||||
]);
|
||||
|
||||
Db::commit();
|
||||
} catch (\Throwable $e) {
|
||||
Db::rollback();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
Log::info('Cleared diagnosis assistant (prescription shipped/signed), assign log written', [
|
||||
'source' => $source,
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'prescription_order_id' => $orderId,
|
||||
'tracking_id' => $trackingId,
|
||||
'fulfillment_status' => $fs,
|
||||
'former_assistant_id' => $oldAssistant,
|
||||
'tracking_id' => $trackingId,
|
||||
'fulfillment_status' => $fs,
|
||||
'former_assistant_id' => $fromAssistantId,
|
||||
]);
|
||||
|
||||
return [
|
||||
'action' => 'cleared',
|
||||
'source' => $source,
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'action' => 'cleared',
|
||||
'source' => $source,
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'prescription_order_id' => $orderId,
|
||||
'tracking_id' => $trackingId,
|
||||
'tracking_number' => $tn,
|
||||
'former_assistant_id' => $oldAssistant,
|
||||
'fulfillment_status' => $fs,
|
||||
'tracking_id' => $trackingId,
|
||||
'tracking_number' => $tn,
|
||||
'former_assistant_id' => (string) $fromAssistantId,
|
||||
'fulfillment_status' => $fs,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('applyAssistantReleaseForShippedPrescriptionOrder failed: ' . $e->getMessage(), [
|
||||
'source' => $source,
|
||||
'source' => $source,
|
||||
'order_id' => $orderId,
|
||||
]);
|
||||
|
||||
@@ -338,19 +359,20 @@ class ExpressTrackingService
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 是否存在「由原医助改派到新医助」的指派记录(两端 admin 均大于 0)。有此记录则已发货自动释放医助不执行。
|
||||
*/
|
||||
private static function diagnosisHasFormalAssistantReassignInAssignLog(int $diagnosisId): bool
|
||||
{
|
||||
if ($diagnosisId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DiagnosisAssignLog::where('diagnosis_id', $diagnosisId)
|
||||
->where('from_assistant_id', '>', 0)
|
||||
->where('to_assistant_id', '>', 0)
|
||||
->count() > 0;
|
||||
}
|
||||
|
||||
private static function maybeClearDiagnosisAssistantWhenShippedPrescription(ExpressTracking $tracking): ?array
|
||||
{
|
||||
if ((string) $tracking->order_type !== 'prescription') {
|
||||
@@ -368,14 +390,14 @@ class ExpressTrackingService
|
||||
}
|
||||
|
||||
return self::applyAssistantReleaseForShippedPrescriptionOrder($order, [
|
||||
'tracking_id' => (int) $tracking->id,
|
||||
'tracking_id' => (int) $tracking->id,
|
||||
'tracking_number' => (string) $tracking->tracking_number,
|
||||
'source' => 'express_auto_update',
|
||||
'source' => 'express_auto_update',
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('maybeClearDiagnosisAssistantWhenShippedPrescription failed: ' . $e->getMessage(), [
|
||||
'tracking_id' => (int) $tracking->id,
|
||||
'order_id' => $orderId,
|
||||
'order_id' => $orderId,
|
||||
]);
|
||||
|
||||
return null;
|
||||
@@ -528,6 +550,54 @@ class ExpressTrackingService
|
||||
$log->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按处方订单履约核对:已发货(5)/已签收(6) 时诊单仍挂在医助的,一律释放并写指派日志。
|
||||
* 与快递 100 / 甘草来自哪个物流渠道无关,保障「已发货」后患者侧医助被清掉。
|
||||
*
|
||||
* @return array{scanned: int, cleared: int, lines: list<string>}
|
||||
*/
|
||||
public static function reconcileAssistantReleaseForShippedPrescriptionOrders(int $limit = 200): array
|
||||
{
|
||||
$dTable = (new Diagnosis())->getTable();
|
||||
$orders = PrescriptionOrder::alias('po')
|
||||
->join($dTable . ' d', 'd.id = po.diagnosis_id')
|
||||
->whereNull('po.delete_time')
|
||||
->whereNull('d.delete_time')
|
||||
->whereIn('po.fulfillment_status', [5, 6])
|
||||
->where('po.diagnosis_id', '>', 0)
|
||||
->where('d.assistant_id', '>', 0)
|
||||
->order('po.id', 'asc')
|
||||
->limit($limit)
|
||||
->field('po.*')
|
||||
->select();
|
||||
|
||||
$cleared = 0;
|
||||
$lines = [];
|
||||
foreach ($orders as $order) {
|
||||
$sync = self::applyAssistantReleaseForShippedPrescriptionOrder($order, [
|
||||
'source' => 'shipped_fulfillment_reconcile',
|
||||
'tracking_number' => (string) ($order->tracking_number ?? ''),
|
||||
]);
|
||||
if (is_array($sync) && ($sync['action'] ?? '') === 'cleared') {
|
||||
$cleared++;
|
||||
$lines[] = 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'scanned' => count($orders),
|
||||
'cleared' => $cleared,
|
||||
'lines' => $lines,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量自动更新(定时任务调用)
|
||||
*
|
||||
@@ -539,7 +609,7 @@ class ExpressTrackingService
|
||||
* assistant_cleared: int,
|
||||
* assistant_skipped_assign_log: int,
|
||||
* assistant_lines: list<string>
|
||||
* }
|
||||
* } assistant_skipped_assign_log 保留兼容恒为 0(已发货/签收一律写指派日志并清空医助)
|
||||
*/
|
||||
public static function autoUpdateBatch(int $limit = 50): array
|
||||
{
|
||||
@@ -580,7 +650,6 @@ class ExpressTrackingService
|
||||
$success = 0;
|
||||
$failed = 0;
|
||||
$assistantCleared = 0;
|
||||
$assistantSkippedAssign = 0;
|
||||
$assistantLines = [];
|
||||
|
||||
foreach ($list as $tracking) {
|
||||
@@ -593,24 +662,13 @@ class ExpressTrackingService
|
||||
if ($act === 'cleared') {
|
||||
$assistantCleared++;
|
||||
$assistantLines[] = sprintf(
|
||||
'[移除医助] 诊单=%d 业务订单=%d 运单=%s 原医助ID=%s 履约状态=%d',
|
||||
'[移除医助+指派日志] 诊单=%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) {
|
||||
@@ -628,7 +686,7 @@ class ExpressTrackingService
|
||||
'success' => $success,
|
||||
'failed' => $failed,
|
||||
'assistant_cleared' => $assistantCleared,
|
||||
'assistant_skipped_assign_log' => $assistantSkippedAssign,
|
||||
'assistant_skipped_assign_log' => 0,
|
||||
'assistant_lines' => $assistantLines,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user