This commit is contained in:
Your Name
2026-05-07 11:50:48 +08:00
parent 9d405ebed9
commit c4dd196e72
6 changed files with 842 additions and 219 deletions
@@ -891,25 +891,31 @@ class PrescriptionOrderLogic
}
/**
* 挂号预约简要信息(业务订单详情展示
* 渠道字典 value => 名称(与挂号 channel_source 存值一致
*
* @return array<string, mixed>|null
* @return array<string, string>
*/
private static function buildAppointmentBrief(int $appointmentId): ?array
private static function channelSourceDictMap(): array
{
if ($appointmentId <= 0) {
return null;
}
$ap = Appointment::find($appointmentId);
if ($ap === null) {
return null;
}
$row = $ap->toArray();
$doctorName = '';
$did = (int) ($row['doctor_id'] ?? 0);
if ($did > 0) {
$doctorName = (string) (Admin::where('id', $did)->value('name') ?? '');
try {
/** @var array<string, string> $m */
$m = Db::name('dict_data')->where('type_value', 'channels')->column('name', 'value');
return $m;
} catch (\Throwable) {
return [];
}
}
/**
* @param array<string, mixed> $row doctor_appointment 行
* @param array<string, string> $channelDict
*
* @return array<string, mixed>
*/
private static function formatAppointmentBriefFromRow(array $row, string $doctorName, array $channelDict = []): array
{
$apptId = (int) ($row['id'] ?? 0);
$statusMap = [
1 => '已预约',
2 => '已取消',
@@ -929,9 +935,28 @@ class PrescriptionOrderLogic
}
$status = (int) ($row['status'] ?? 0);
$atype = (string) ($row['appointment_type'] ?? '');
$chSrc = trim((string) ($row['channel_source'] ?? ''));
if ($chSrc === '') {
$legacy = $row['channels'] ?? null;
if ($legacy !== null && $legacy !== '') {
$chSrc = is_numeric($legacy)
? (string) (int) $legacy
: trim((string) $legacy);
}
}
$chDesc = '';
if ($chSrc !== '') {
$chDesc = (string) ($channelDict[$chSrc] ?? '');
if ($chDesc === '' && is_numeric($chSrc)) {
$chDesc = (string) ($channelDict[(string) (int) $chSrc] ?? '');
}
if ($chDesc === '') {
$chDesc = $chSrc;
}
}
return [
'id' => $appointmentId,
'id' => $apptId,
'appointment_date' => (string) ($row['appointment_date'] ?? ''),
'period' => $period,
'appointment_time' => $timePart,
@@ -940,11 +965,144 @@ class PrescriptionOrderLogic
'status' => $status,
'status_desc' => $statusMap[$status] ?? '未知',
'doctor_name' => $doctorName,
'channel_source' => (string) ($row['channel_source'] ?? ''),
'channel_source' => $chSrc,
'channel_source_desc' => $chDesc,
'remark' => (string) ($row['remark'] ?? ''),
];
}
/**
* 挂号预约简要信息(业务订单详情展示)
*
* @return array<string, mixed>|null
*/
private static function buildAppointmentBrief(int $appointmentId): ?array
{
if ($appointmentId <= 0) {
return null;
}
$ap = Appointment::find($appointmentId);
if ($ap === null) {
return null;
}
$row = $ap->toArray();
$doctorName = '';
$did = (int) ($row['doctor_id'] ?? 0);
if ($did > 0) {
$doctorName = (string) (Admin::where('id', $did)->value('name') ?? '');
}
$channelDict = self::channelSourceDictMap();
return self::formatAppointmentBriefFromRow($row, $doctorName, $channelDict);
}
/**
* 业务订单列表行批量附加 linked_appointment(解析规则与详情一致:优先处方 appointment_id,否则诊单最近一条预约)
*
* @param array<int, array<string, mixed>> $lists
*/
public static function appendLinkedAppointmentsToListRows(array &$lists): void
{
if ($lists === []) {
return;
}
foreach ($lists as &$item) {
$item['linked_appointment'] = null;
}
unset($item);
$rxIds = array_values(array_unique(array_filter(array_map(
static fn ($x) => (int) ($x['prescription_id'] ?? 0),
$lists
))));
$rxApptByRx = [];
if ($rxIds !== []) {
$rxApptByRx = Prescription::whereIn('id', $rxIds)->whereNull('delete_time')->column('appointment_id', 'id');
}
$diagNeedFallback = [];
foreach ($lists as $item) {
$rxId = (int) ($item['prescription_id'] ?? 0);
$dgId = (int) ($item['diagnosis_id'] ?? 0);
$apFromRx = $rxId > 0 ? (int) ($rxApptByRx[$rxId] ?? 0) : 0;
if ($apFromRx <= 0 && $dgId > 0) {
$diagNeedFallback[$dgId] = true;
}
}
$diagIds = array_keys($diagNeedFallback);
$latestApptByDiag = [];
if ($diagIds !== []) {
try {
$agg = Db::name('doctor_appointment')
->whereIn('patient_id', $diagIds)
->fieldRaw('patient_id, MAX(id) as max_id')
->group('patient_id')
->select()
->toArray();
foreach ($agg as $r) {
$pid = (int) ($r['patient_id'] ?? 0);
$mid = (int) ($r['max_id'] ?? 0);
if ($pid > 0 && $mid > 0) {
$latestApptByDiag[$pid] = $mid;
}
}
} catch (\Throwable) {
$latestApptByDiag = [];
}
}
/** @var array<int, array{0: int, 1: int}> $resolvedPairs index => [ resolvedApptId, rxAppointmentId ] */
$resolvedPairs = [];
foreach ($lists as $idx => $item) {
$rxId = (int) ($item['prescription_id'] ?? 0);
$dgId = (int) ($item['diagnosis_id'] ?? 0);
$rxApptId = $rxId > 0 ? (int) ($rxApptByRx[$rxId] ?? 0) : 0;
$resolved = $rxApptId;
if ($resolved <= 0 && $dgId > 0) {
$resolved = (int) ($latestApptByDiag[$dgId] ?? 0);
}
if ($resolved > 0) {
$resolvedPairs[$idx] = [$resolved, $rxApptId];
}
}
if ($resolvedPairs === []) {
return;
}
$allApptIds = array_values(array_unique(array_map(static fn ($p) => $p[0], $resolvedPairs)));
$appts = Appointment::whereIn('id', $allApptIds)->select()->toArray();
$apptById = [];
foreach ($appts as $a) {
$aid = (int) ($a['id'] ?? 0);
if ($aid > 0) {
$apptById[$aid] = $a;
}
}
$doctorIds = array_values(array_unique(array_filter(array_map(
static fn ($a) => (int) ($a['doctor_id'] ?? 0),
$appts
))));
$doctorNames = [];
if ($doctorIds !== []) {
$doctorNames = Admin::whereIn('id', $doctorIds)->column('name', 'id');
}
$channelDict = self::channelSourceDictMap();
foreach ($resolvedPairs as $idx => $pair) {
$resolvedId = $pair[0];
$rxApptId = $pair[1];
$row = $apptById[$resolvedId] ?? null;
if ($row === null || !is_array($row)) {
continue;
}
$did = (int) ($row['doctor_id'] ?? 0);
$dname = $did > 0 ? (string) ($doctorNames[$did] ?? '') : '';
$brief = self::formatAppointmentBriefFromRow($row, $dname, $channelDict);
$brief['resolved_from'] = $rxApptId === $resolvedId ? 'prescription' : 'diagnosis';
$lists[$idx]['linked_appointment'] = $brief;
}
}
/**
* 物流轨迹(顺丰/京东等,优先快递100;未配置密钥时返回官网链接)
*