This commit is contained in:
gr
2026-11-05 17:28:39 +08:00
9 changed files with 894 additions and 18 deletions
@@ -98,6 +98,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
// 关键字:待分配 Tab 用多字段宽搜;其它 Tab 仍为姓名/手机。
$this->applyDiagnosisListKeywordFilter($query, $pendingAssign);
$this->applyDoctorNameFilter($query, $pendingWideSearch);
// 待分配医助列表:assistant_id 为 NULL 或 0(宽搜不加此条件)
if ($narrowPendingAssignPool) {
@@ -191,7 +192,11 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
$appointmentMap = [];
$subQuery = Appointment::where('patient_id', 'in', $diagnosisIds)
->where('status', 'in', [1, 3, 4]); // 1=已预约 3=已完成 4=已过号
if (!empty($this->params['appointment_date'])) {
$doctorConditions = $this->doctorAppointmentConditions($pendingWideSearch, (new Appointment())->getTable());
if ($doctorConditions !== null) {
// 根级操作挂号与嵌套预约必须使用筛选命中的挂号,不能取该患者其他医生的第一条预约。
$subQuery->whereRaw($doctorConditions[0], $doctorConditions[1]);
} elseif (!$pendingWideSearch && !empty($this->params['appointment_date'])) {
$subQuery->where('appointment_date', (string) $this->params['appointment_date']);
}
@@ -568,6 +573,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
}
$this->applyDiagnosisListKeywordFilter($query, $pendingAssign);
$this->applyDoctorNameFilter($query, $pendingWideSearch);
if ($narrowPendingAssignPool) {
$query->whereRaw('(assistant_id IS NULL OR assistant_id = 0)');
@@ -643,6 +649,60 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
$this->applyPendingAssignBusinessOrderMonthFilter($query);
return $query->count();
}
/**
* 医生姓名按有效挂号关联;日期、状态必须命中同一条挂号,避免历史医生串入当前队列。
* EXISTS 在分页前执行且与 count 共用,不会因同医生的多次挂号重复计数。
*/
private function applyDoctorNameFilter($query, bool $pendingWideSearch): void
{
$doctorConditions = $this->doctorAppointmentConditions($pendingWideSearch, 'doctor_apt');
if ($doctorConditions === null) {
return;
}
$aptTbl = (new Appointment())->getTable();
$diagTbl = (new Diagnosis())->getTable();
$query->whereExists(new \think\db\Raw(
"SELECT 1 FROM {$aptTbl} doctor_apt WHERE doctor_apt.patient_id = {$diagTbl}.id AND " . $doctorConditions[0],
$doctorConditions[1]
));
}
/**
* 列表/count 的诊单筛选与列表预约组装共用条件,保证医生、日期、状态来自同一挂号。
* @return array{0:string,1:array}|null
*/
private function doctorAppointmentConditions(bool $pendingWideSearch, string $appointmentAlias): ?array
{
$doctorName = trim((string) ($this->params['doctor_name'] ?? ''));
if ($doctorName === '') {
return null;
}
$adminTbl = (new Admin())->getTable();
$conditions = [
"{$appointmentAlias}.status IN (" . implode(',', self::EFFECTIVE_APPOINTMENT_STATUSES) . ')',
"EXISTS (SELECT 1 FROM {$adminTbl} filter_doctor WHERE filter_doctor.id = {$appointmentAlias}.doctor_id"
. ' AND filter_doctor.delete_time IS NULL AND filter_doctor.name LIKE :diagnosis_doctor_name)',
];
$bindings = ['diagnosis_doctor_name' => '%' . $doctorName . '%'];
// 待分配关键词宽搜保持原有日期/状态豁免,但仍尊重明确输入的医生姓名。
if (!$pendingWideSearch) {
if (!empty($this->params['appointment_date'])) {
$conditions[] = "{$appointmentAlias}.appointment_date = :diagnosis_doctor_date";
$bindings['diagnosis_doctor_date'] = (string) $this->params['appointment_date'];
}
if (isset($this->params['appointment_status']) && $this->params['appointment_status'] !== '') {
$conditions[] = "{$appointmentAlias}.status = :diagnosis_doctor_status";
$bindings['diagnosis_doctor_status'] = (int) $this->params['appointment_status'];
}
if (isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1') {
$conditions[] = "{$appointmentAlias}.status = 3";
}
}
return [implode(' AND ', $conditions), $bindings];
}
/**