更新
This commit is contained in:
@@ -64,36 +64,35 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
|
||||
// 待分配医助筛选:assistant_id 为空或 0(放在最前面判断,便于跳过医助角色的自我过滤)
|
||||
$pendingAssign = isset($this->params['pending_assign']) && (string) $this->params['pending_assign'] === '1';
|
||||
$pendingWideSearch = $this->isPendingAssignWideKeywordSearchActive();
|
||||
// 仅「待分配列表」收窄到未分配医助;宽搜不套此池,与「全部」一致可命中已分配医助的诊单
|
||||
$narrowPendingAssignPool = $pendingAssign && !$pendingWideSearch;
|
||||
|
||||
// 构建查询
|
||||
$query = Diagnosis::where($this->searchWhere);
|
||||
// 构建查询(待分配+关键词检索时不带诊单启用/禁用 status 条件,并弱化挂号/确认等 Tab 残留参数)
|
||||
$baseWhere = $pendingWideSearch
|
||||
? $this->searchWhereWithoutDiagnosisStatus($this->searchWhere)
|
||||
: $this->searchWhere;
|
||||
$query = Diagnosis::where($baseWhere);
|
||||
|
||||
// 如果是医助角色(role_id=2),只显示自己添加的患者;
|
||||
// 但当前在查"待分配医助"时应放开,否则 NULL 记录永远不会匹配 assistant_id=adminId
|
||||
if (in_array(2, $roleIds) && !$pendingAssign) {
|
||||
// 如果是医助角色(role_id=2),只显示自己关联的诊单;待分配列表(未宽搜)放开以便看到全体未分配记录
|
||||
if (in_array(2, $roleIds) && (!$pendingAssign || $pendingWideSearch)) {
|
||||
$query->where('assistant_id', $this->adminId);
|
||||
}
|
||||
|
||||
if (!$pendingAssign) {
|
||||
if (!$pendingAssign || $pendingWideSearch) {
|
||||
$this->applyDataScopeByOwner($query, 'assistant_id');
|
||||
}
|
||||
|
||||
// 关键字搜索:支持患者姓名或手机号(模糊匹配)
|
||||
if (isset($this->params['keyword']) && trim((string) $this->params['keyword']) !== '') {
|
||||
$keyword = trim((string) $this->params['keyword']);
|
||||
$query->where(function ($q) use ($keyword) {
|
||||
$q->whereLike('patient_name', '%' . $keyword . '%')
|
||||
->whereOr('phone', 'like', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
// 关键字:待分配 Tab 用多字段宽搜;其它 Tab 仍为姓名/手机。窄「待分配列表」不套数据权限;宽搜与「全部」一致会套数据权限。
|
||||
$this->applyDiagnosisListKeywordFilter($query, $pendingAssign);
|
||||
|
||||
// 待分配医助:assistant_id 为 NULL 或 0(使用 whereRaw 避免闭包 whereOr 歧义)
|
||||
if ($pendingAssign) {
|
||||
// 待分配医助列表:assistant_id 为 NULL 或 0(宽搜不加此条件)
|
||||
if ($narrowPendingAssignPool) {
|
||||
$query->whereRaw('(assistant_id IS NULL OR assistant_id = 0)');
|
||||
}
|
||||
|
||||
// 是否确认诊单:1=已确认 0=未确认
|
||||
if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
// 是否确认诊单:1=已确认 0=未确认(待分配+关键词检索时不限制确认态,避免搜不到)
|
||||
if (!$pendingWideSearch && isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
$confirmed = (int)$this->params['diagnosis_confirmed'];
|
||||
$dvrTbl = (new DiagnosisViewRecord())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
@@ -105,16 +104,16 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
}
|
||||
|
||||
// 挂号日期筛选:当天/明天/后天(1=已预约 3=已完成 4=已过号,需展示以便取消等操作)
|
||||
if (!empty($this->params['appointment_date'])) {
|
||||
// 挂号日期筛选:当天/明天/后天…(待分配+关键词检索时不限制日期)
|
||||
if (!$pendingWideSearch && !empty($this->params['appointment_date'])) {
|
||||
$aptDate = addslashes($this->params['appointment_date']);
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$aptTbl} apt WHERE apt.patient_id = {$diagTbl}.id AND apt.appointment_date = '{$aptDate}' AND apt.status IN (1,3,4)");
|
||||
}
|
||||
|
||||
// 挂号状态:1=已挂号(含已预约/已完成/已过号)0=未挂号
|
||||
if (isset($this->params['has_appointment']) && $this->params['has_appointment'] !== '') {
|
||||
// 挂号状态:1=已挂号 0=未挂号(待分配+关键词检索时不限制)
|
||||
if (!$pendingWideSearch && isset($this->params['has_appointment']) && $this->params['has_appointment'] !== '') {
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
if ((int)$this->params['has_appointment'] === 1) {
|
||||
@@ -124,8 +123,8 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
}
|
||||
|
||||
// 至少有一条挂号为「已完成」(status=3),用于列表顶部「已完成」Tab
|
||||
if (isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1') {
|
||||
// 至少有一条挂号为「已完成」(status=3)(待分配+关键词检索时不限制)
|
||||
if (!$pendingWideSearch && isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1') {
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$aptTbl} apt WHERE apt.patient_id = {$diagTbl}.id AND apt.status = 3");
|
||||
@@ -133,15 +132,15 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
|
||||
$this->applyPendingAssignBusinessOrderMonthFilter($query);
|
||||
|
||||
// 仅已开方(有处方)的诊单:随访列表传 only_has_prescription=1;问诊等页面不传则不过滤
|
||||
if (isset($this->params['only_has_prescription']) && (string) $this->params['only_has_prescription'] === '1') {
|
||||
// 仅已开方(待分配+关键词检索时不限制)
|
||||
if (!$pendingWideSearch && isset($this->params['only_has_prescription']) && (string) $this->params['only_has_prescription'] === '1') {
|
||||
$rxTbl = (new Prescription())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$rxTbl} rx WHERE rx.diagnosis_id = {$diagTbl}.id AND rx.delete_time IS NULL");
|
||||
}
|
||||
|
||||
// 医助所属部门(随访等页面传 assistant_dept_id):选父级时包含全部子级部门下医助
|
||||
if (isset($this->params['assistant_dept_id']) && $this->params['assistant_dept_id'] !== '' && (int) $this->params['assistant_dept_id'] > 0) {
|
||||
// 医助所属部门(待分配+关键词检索时不按部门收窄)
|
||||
if (!$pendingWideSearch && isset($this->params['assistant_dept_id']) && $this->params['assistant_dept_id'] !== '' && (int) $this->params['assistant_dept_id'] > 0) {
|
||||
$rootDeptId = (int) $this->params['assistant_dept_id'];
|
||||
$deptIds = DeptLogic::getSelfAndDescendantIds($rootDeptId);
|
||||
$deptIds = array_values(array_filter(array_map('intval', $deptIds), static function (int $id): bool {
|
||||
@@ -162,7 +161,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$minAptDateCond = '';
|
||||
if (!empty($this->params['appointment_date'])) {
|
||||
if (!$pendingWideSearch && !empty($this->params['appointment_date'])) {
|
||||
$sortAptDate = addslashes((string) $this->params['appointment_date']);
|
||||
$minAptDateCond = " AND apt.appointment_date = '{$sortAptDate}'";
|
||||
}
|
||||
@@ -173,8 +172,8 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
// 获取最早的挂号时间(用于同状态内排序)
|
||||
$minAptExpr = '(SELECT MIN(CONCAT(apt.appointment_date, \' \', IFNULL(NULLIF(TRIM(apt.appointment_time), \'\'), \'00:00:00\'))) FROM ' . $aptTbl . ' apt WHERE apt.patient_id = ' . $diagTbl . '.id AND apt.status IN (1,3,4)' . $minAptDateCond . ')';
|
||||
|
||||
// 「已完成」Tab:按最近一条「已完成」(status=3) 挂号日期+时间降序,最新在最前;有 appointment_date 时仍只在该日内比
|
||||
$isCompletedTab = isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1';
|
||||
// 「已完成」Tab:按最近一条「已完成」(status=3) 挂号日期+时间降序…
|
||||
$isCompletedTab = !$pendingWideSearch && isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1';
|
||||
if ($isCompletedTab) {
|
||||
$maxCompletedAptExpr = '(SELECT MAX(CONCAT(apt.appointment_date, \' \', IFNULL(NULLIF(TRIM(apt.appointment_time), \'\'), \'00:00:00\'))) FROM ' . $aptTbl . ' apt WHERE apt.patient_id = ' . $diagTbl . '.id AND apt.status = 3' . $minAptDateCond . ')';
|
||||
$orderRaw = 'IFNULL(' . $maxCompletedAptExpr . ", '1970-01-01 00:00:00') DESC, {$diagTbl}.id DESC";
|
||||
@@ -481,33 +480,29 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$pendingAssign = isset($this->params['pending_assign']) && (string) $this->params['pending_assign'] === '1';
|
||||
|
||||
// 构建查询
|
||||
$query = Diagnosis::where($this->searchWhere);
|
||||
$pendingWideSearch = $this->isPendingAssignWideKeywordSearchActive();
|
||||
$narrowPendingAssignPool = $pendingAssign && !$pendingWideSearch;
|
||||
$baseWhere = $pendingWideSearch
|
||||
? $this->searchWhereWithoutDiagnosisStatus($this->searchWhere)
|
||||
: $this->searchWhere;
|
||||
$query = Diagnosis::where($baseWhere);
|
||||
|
||||
// 如果是医助角色(role_id=2),只显示自己添加的患者;查"待分配医助"时放开
|
||||
if (in_array(2, $roleIds) && !$pendingAssign) {
|
||||
if (in_array(2, $roleIds) && (!$pendingAssign || $pendingWideSearch)) {
|
||||
$query->where('assistant_id', $this->adminId);
|
||||
}
|
||||
|
||||
if (!$pendingAssign) {
|
||||
if (!$pendingAssign || $pendingWideSearch) {
|
||||
$this->applyDataScopeByOwner($query, 'assistant_id');
|
||||
}
|
||||
|
||||
// 关键字搜索:支持患者姓名或手机号(模糊匹配)
|
||||
if (isset($this->params['keyword']) && trim((string) $this->params['keyword']) !== '') {
|
||||
$keyword = trim((string) $this->params['keyword']);
|
||||
$query->where(function ($q) use ($keyword) {
|
||||
$q->whereLike('patient_name', '%' . $keyword . '%')
|
||||
->whereOr('phone', 'like', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
$this->applyDiagnosisListKeywordFilter($query, $pendingAssign);
|
||||
|
||||
// 待分配医助:assistant_id 为 NULL 或 0
|
||||
if ($pendingAssign) {
|
||||
if ($narrowPendingAssignPool) {
|
||||
$query->whereRaw('(assistant_id IS NULL OR assistant_id = 0)');
|
||||
}
|
||||
|
||||
// 是否确认诊单
|
||||
if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
if (!$pendingWideSearch && isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
|
||||
$confirmed = (int)$this->params['diagnosis_confirmed'];
|
||||
$dvrTbl = (new DiagnosisViewRecord())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
@@ -520,7 +515,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
|
||||
// 挂号日期筛选
|
||||
if (!empty($this->params['appointment_date'])) {
|
||||
if (!$pendingWideSearch && !empty($this->params['appointment_date'])) {
|
||||
$aptDate = addslashes($this->params['appointment_date']);
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
@@ -528,7 +523,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
|
||||
// 挂号状态
|
||||
if (isset($this->params['has_appointment']) && $this->params['has_appointment'] !== '') {
|
||||
if (!$pendingWideSearch && isset($this->params['has_appointment']) && $this->params['has_appointment'] !== '') {
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
if ((int)$this->params['has_appointment'] === 1) {
|
||||
@@ -539,23 +534,140 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
}
|
||||
|
||||
// 至少有一条挂号为「已完成」(status=3)
|
||||
if (isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1') {
|
||||
if (!$pendingWideSearch && isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1') {
|
||||
$aptTbl = (new Appointment())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$aptTbl} apt WHERE apt.patient_id = {$diagTbl}.id AND apt.status = 3");
|
||||
}
|
||||
|
||||
// 仅已开方(待分配+关键词检索时不限制)
|
||||
if (!$pendingWideSearch && isset($this->params['only_has_prescription']) && (string) $this->params['only_has_prescription'] === '1') {
|
||||
$rxTbl = (new Prescription())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$rxTbl} rx WHERE rx.diagnosis_id = {$diagTbl}.id AND rx.delete_time IS NULL");
|
||||
}
|
||||
|
||||
// 医助所属部门(待分配+关键词检索时不按部门收窄)
|
||||
if (!$pendingWideSearch && isset($this->params['assistant_dept_id']) && $this->params['assistant_dept_id'] !== '' && (int) $this->params['assistant_dept_id'] > 0) {
|
||||
$rootDeptId = (int) $this->params['assistant_dept_id'];
|
||||
$deptIds = DeptLogic::getSelfAndDescendantIds($rootDeptId);
|
||||
$deptIds = array_values(array_filter(array_map('intval', $deptIds), static function (int $id): bool {
|
||||
return $id > 0;
|
||||
}));
|
||||
if ($deptIds === []) {
|
||||
$query->whereRaw('0 = 1');
|
||||
} else {
|
||||
$inList = implode(',', $deptIds);
|
||||
$adTbl = (new AdminDept())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->whereExists("SELECT 1 FROM {$adTbl} ad WHERE ad.admin_id = {$diagTbl}.assistant_id AND ad.dept_id IN ({$inList})");
|
||||
}
|
||||
}
|
||||
|
||||
$this->applyPendingAssignBusinessOrderMonthFilter($query);
|
||||
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 待分配 Tab 且有关键词时:放宽列表条件(与 `applyDiagnosisListKeywordFilter` 判定一致)。
|
||||
*/
|
||||
private function isPendingAssignWideKeywordSearchActive(): bool
|
||||
{
|
||||
$pending = isset($this->params['pending_assign']) && (string) $this->params['pending_assign'] === '1';
|
||||
if (!$pending) {
|
||||
return false;
|
||||
}
|
||||
$wideKw = trim((string) ($this->params['pending_assign_keyword'] ?? ''));
|
||||
if ($wideKw === '') {
|
||||
$wideKw = trim((string) ($this->params['keyword'] ?? ''));
|
||||
}
|
||||
|
||||
return $wideKw !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 `createWhere` 结果中移除诊单 `status`(启用/禁用),便于宽检索命中任意状态诊单。
|
||||
*
|
||||
* @param list<array{0:mixed,1?:mixed,2?:mixed}> $searchWhere
|
||||
* @return list<array{0:mixed,1?:mixed,2?:mixed}>
|
||||
*/
|
||||
private function searchWhereWithoutDiagnosisStatus(array $searchWhere): array
|
||||
{
|
||||
$out = [];
|
||||
foreach ($searchWhere as $cond) {
|
||||
if (is_array($cond) && isset($cond[0]) && $cond[0] === 'status') {
|
||||
continue;
|
||||
}
|
||||
$out[] = $cond;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表关键字:待分配医助 Tab 为「多字段」检索(pending_assign_keyword 优先,否则回落 keyword);
|
||||
* 其它 Tab 仍为姓名、手机。待分配 Tab 本身已不套 assistant_id 数据权限,检索可触达全部待分配诊单。
|
||||
*/
|
||||
private function applyDiagnosisListKeywordFilter($query, bool $pendingAssign): void
|
||||
{
|
||||
if ($pendingAssign) {
|
||||
$wideKw = trim((string) ($this->params['pending_assign_keyword'] ?? ''));
|
||||
if ($wideKw === '') {
|
||||
$wideKw = trim((string) ($this->params['keyword'] ?? ''));
|
||||
}
|
||||
if ($wideKw !== '') {
|
||||
$this->applyPendingAssignWideKeywordSearch($query, $wideKw);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->params['keyword']) && trim((string) $this->params['keyword']) !== '') {
|
||||
$keyword = trim((string) $this->params['keyword']);
|
||||
$query->where(function ($q) use ($keyword) {
|
||||
$q->whereLike('patient_name', '%' . $keyword . '%')
|
||||
->whereOr('phone', 'like', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 待分配医助场景:多列模糊 + 纯数字时诊单 id / 患者号精确匹配。
|
||||
*/
|
||||
private function applyPendingAssignWideKeywordSearch($query, string $keyword): void
|
||||
{
|
||||
$kw = trim($keyword);
|
||||
if ($kw === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$query->where(function ($q) use ($kw) {
|
||||
$q->whereLike('patient_name', '%' . $kw . '%')
|
||||
->whereOr('phone', 'like', '%' . $kw . '%')
|
||||
->whereOr('id_card', 'like', '%' . $kw . '%')
|
||||
->whereOr('remark', 'like', '%' . $kw . '%')
|
||||
->whereOr('symptoms', 'like', '%' . $kw . '%')
|
||||
->whereOr('current_medications', 'like', '%' . $kw . '%');
|
||||
if (preg_match('/^\d+$/', $kw)) {
|
||||
$n = (int) $kw;
|
||||
if ($n > 0) {
|
||||
$q->whereOr('id', '=', $n)
|
||||
->whereOr('patient_id', '=', $n);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 「待分配医助」Tab:按月份筛选——诊单在指定自然月内需存在业务订单(order.patient_id = 诊单 id)
|
||||
* create_time 兼容整型时间戳与 datetime 字符串
|
||||
*/
|
||||
private function applyPendingAssignBusinessOrderMonthFilter($query): void
|
||||
{
|
||||
if ($this->isPendingAssignWideKeywordSearchActive()) {
|
||||
return;
|
||||
}
|
||||
$pendingAssign = isset($this->params['pending_assign']) && (string) $this->params['pending_assign'] === '1';
|
||||
if (!$pendingAssign || empty($this->params['pending_assign_order_month'])) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user