This commit is contained in:
gr
2026-10-15 11:03:54 +08:00
parent 70ddc1a70a
commit bb28d93cec
64 changed files with 12747 additions and 420 deletions
@@ -38,6 +38,9 @@ use app\common\service\AppointmentCallPolicy;
use app\common\service\FileService;
use app\common\service\DataScope\DataScopeService;
use app\common\service\storage\Driver as StorageDriver;
use app\common\service\tcm\RevisitDueHook;
use app\common\service\tcm\RevisitDueService;
use app\common\service\tcm\RevisitVisitSlotService;
use think\facade\Db;
/**
* 中医辨房病因诊单逻辑
@@ -260,6 +263,10 @@ class DiagnosisLogic extends BaseLogic
{
try {
Diagnosis::destroy($params['id']);
// 诊单删除后把复诊到期快照推进为失效(Hook 内部吞异常,不影响删除结果)
foreach ((array) $params['id'] as $deletedId) {
RevisitDueHook::onDiagnosisChanged((int) $deletedId, 'delete');
}
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
@@ -707,6 +714,15 @@ class DiagnosisLogic extends BaseLogic
if ($fromAssistantId <= 0 && $toAssistantId > 0) {
$fromAssistantId = self::inferPreviousAssistantIdFromLatestAssignLog($id);
}
// from == to(指派给自己)不硬拦:批量指派流程不中断,复诊接诊率 slot 口径统计时忽略该行;前端弹窗负责提示
// 继承时患者所处诊次快照(继承时刻之前的有效实单数 + 偏移;统计以实时重算为准,本列供指派记录面板展示/对账)
$inheritVisitSlot = 0;
$inheritVisitSlotCalcTime = 0;
if ($isInherit === 1) {
$inheritVisitSlot = min(255, max(0, RevisitVisitSlotService::slotAtTime($id, $now)));
$inheritVisitSlotCalcTime = $now;
}
Db::name('tcm_diagnosis')
->where('id', $id)
@@ -720,17 +736,19 @@ class DiagnosisLogic extends BaseLogic
$admin = $req->adminInfo ?? [];
// Db::insert 直写:与 assignLogList 一致,避免模型 allowField/schema 丢列
Db::name('tcm_diagnosis_assign_log')->insert([
'diagnosis_id' => $id,
'from_assistant_id' => $fromAssistantId,
'to_assistant_id' => $toAssistantId,
'operator_admin_id' => (int) ($admin['admin_id'] ?? 0),
'operator_name' => (string) ($admin['name'] ?? ''),
'operator_account' => (string) ($admin['account'] ?? ''),
'ip' => (string) ($req->ip() ?? ''),
'related_po_creator_id' => $relatedPoCreatorId,
'related_po_create_time' => $relatedPoCreateTime,
'is_inherit' => $isInherit,
'create_time' => $now,
'diagnosis_id' => $id,
'from_assistant_id' => $fromAssistantId,
'to_assistant_id' => $toAssistantId,
'operator_admin_id' => (int) ($admin['admin_id'] ?? 0),
'operator_name' => (string) ($admin['name'] ?? ''),
'operator_account' => (string) ($admin['account'] ?? ''),
'ip' => (string) ($req->ip() ?? ''),
'related_po_creator_id' => $relatedPoCreatorId,
'related_po_create_time' => $relatedPoCreateTime,
'is_inherit' => $isInherit,
'inherit_visit_slot' => $inheritVisitSlot,
'inherit_visit_slot_calc_time' => $inheritVisitSlotCalcTime,
'create_time' => $now,
]);
} catch (\Throwable $e) {
Db::rollback();
@@ -741,6 +759,9 @@ class DiagnosisLogic extends BaseLogic
Db::commit();
// 事务提交后刷新复诊到期快照(换医助重置延迟字段;钩子内部吞异常,不影响指派结果)
RevisitDueHook::onAssistantChanged($id, $toAssistantId, 'assign');
return true;
} catch (\Exception $e) {
Db::rollback();
@@ -785,6 +806,9 @@ class DiagnosisLogic extends BaseLogic
try {
$diagnosis->save(['revisit_slot_start_offset' => $offset]);
// 起始偏移影响 current_slot/next_slot:刷新复诊到期快照(钩子内部吞异常)
RevisitDueHook::onDiagnosisChanged($diagnosisId, 'offset');
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
@@ -849,6 +873,16 @@ class DiagnosisLogic extends BaseLogic
$inherit = (int) ($r['is_inherit'] ?? 0);
$r['is_inherit'] = $inherit;
$r['is_inherit_text'] = $inherit === 1 ? '是' : '否';
// 继承时诊次快照(2026-10 加列前的历史继承行 calc_time=0,无法回溯,文案留空)
$k = (int) ($r['inherit_visit_slot'] ?? 0);
$kCalcTime = (int) ($r['inherit_visit_slot_calc_time'] ?? 0);
$r['inherit_visit_slot'] = $k;
$r['inherit_visit_slot_calc_time'] = $kCalcTime;
if ($inherit === 1 && $kCalcTime > 0) {
$r['inherit_visit_slot_text'] = $k > 0 ? sprintf('继承时第 %d 诊', $k) : '继承时未成交';
} else {
$r['inherit_visit_slot_text'] = '';
}
}
unset($r);
@@ -4281,6 +4315,9 @@ class DiagnosisLogic extends BaseLogic
$unservedDays = $maxRecordTs > 0 ? max(0, (int) floor((time() - $maxRecordTs) / 86400)) : null;
$lastBloodRecordAt = $maxRecordTs > 0 ? date('Y-m-d', $maxRecordTs) : null;
// 7) 复诊到期(契约 C,与诊单列表行 revisit_due 同构;无快照且无法计算时为 state='none')
$revisitDue = RevisitDueService::buildListPayload([$diagnosisId], ['self_heal' => true, 'page_size' => 1])[$diagnosisId] ?? null;
return [
'appointment' => $appointment,
'diagnosis' => $diagnosis,
@@ -4288,6 +4325,7 @@ class DiagnosisLogic extends BaseLogic
'tracking_notes' => $trackingNotes,
'unserved_days' => $unservedDays,
'last_blood_record_at' => $lastBloodRecordAt,
'revisit_due' => $revisitDue,
];
}
@@ -36,6 +36,7 @@ use app\common\service\pharmacy\LockedPharmacySnapshotMutation;
use app\common\service\pharmacy\PharmacySubmissionClaimService;
use app\common\service\pharmacy\PharmacySubmissionClaimWorkflow;
use app\common\service\pharmacy\PharmacySupplyMode;
use app\common\service\tcm\RevisitDueHook;
use think\db\Query;
use think\facade\Config;
use think\facade\Db;
@@ -979,7 +980,7 @@ class PrescriptionOrderLogic
{
self::$error = '';
try {
return Db::transaction(static function () use ($params, $adminId, $adminInfo) {
$created = Db::transaction(static function () use ($params, $adminId, $adminInfo) {
// 先锁始终存在的处方行;空订单集合也能串行化两次创建。
// 首个一致性读发生在获得该锁后,等待者可见前一次创建提交的订单。
$rx = Prescription::where('id', (int) ($params['prescription_id'] ?? 0))
@@ -998,6 +999,13 @@ class PrescriptionOrderLogic
self::$error = $e->getMessage();
return false;
}
// 事务提交后刷新复诊到期快照(新订单开启新周期;钩子内部吞异常,不影响创建结果)
if (is_array($created)) {
RevisitDueHook::onOrderChanged((int) ($created['diagnosis_id'] ?? 0), (int) ($created['id'] ?? 0), 'create');
}
return $created;
}
private static function createLocked(array $params, int $adminId, array $adminInfo)
@@ -1165,7 +1173,7 @@ class PrescriptionOrderLogic
}
try {
return Db::transaction(static function () use ($params, $adminId, $adminInfo) {
$edited = Db::transaction(static function () use ($params, $adminId, $adminInfo) {
$order = PrescriptionOrder::where('id', (int) $params['id'])
->whereNull('delete_time')->lock(true)->find();
if (!$order) {
@@ -1192,6 +1200,13 @@ class PrescriptionOrderLogic
self::$error = $e->getMessage();
return false;
}
// 事务提交后刷新复诊到期快照:下单时间影响锚点/诊次;返回体不含 diagnosis_id,由钩子按订单 id 反查
if (is_array($edited)) {
RevisitDueHook::onOrderChanged(0, (int) ($edited['id'] ?? 0), 'edit_time');
}
return $edited;
}
public static function detail(int $id, int $adminId, array $adminInfo): ?array
@@ -2251,7 +2266,7 @@ class PrescriptionOrderLogic
{
self::setError('');
try {
return LockedPharmacySnapshotMutation::execute(
$withdrawn = LockedPharmacySnapshotMutation::execute(
$id,
static fn () => self::withdrawLocked($id, $adminId, $adminInfo)
);
@@ -2261,6 +2276,13 @@ class PrescriptionOrderLogic
}
return false;
}
// 事务提交后刷新复诊到期快照(撤回置 4,订单退出有效口径;钩子内部吞异常)
if (is_array($withdrawn)) {
RevisitDueHook::onOrderChanged((int) ($withdrawn['diagnosis_id'] ?? 0), $id, 'withdraw');
}
return $withdrawn;
}
private static function withdrawLocked(int $id, int $adminId, array $adminInfo)
@@ -3303,6 +3325,9 @@ class PrescriptionOrderLogic
$logLine
);
// 刷新复诊到期快照(9/10 退出有效口径,终态可能释放医助;钩子内部吞异常)
RevisitDueHook::onOrderChanged((int) $order->diagnosis_id, $id, 'complete:' . $targetFulfillmentStatus);
$out = $order->toArray();
self::maskInternalCostIfNeeded($out, $adminInfo);
self::maskRemarkExtraIfNeeded($out, $adminInfo);
@@ -3478,6 +3503,9 @@ class PrescriptionOrderLogic
self::writeLog($id, $adminId, $adminInfo, 'refund', $logLine);
// 刷新复诊到期快照(全额退款置 10 退出有效口径并可能释放医助;钩子内部吞异常)
RevisitDueHook::onOrderChanged((int) $order->diagnosis_id, $id, 'refund');
$out = $order->toArray();
$out['this_refund_amount'] = $refundAmount;
$out['refund_full'] = $isFullRefund;
File diff suppressed because it is too large Load Diff