diff --git a/server/app/adminapi/lists/tcm/PrescriptionOrderLists.php b/server/app/adminapi/lists/tcm/PrescriptionOrderLists.php index 4c7bbda6..296179ef 100755 --- a/server/app/adminapi/lists/tcm/PrescriptionOrderLists.php +++ b/server/app/adminapi/lists/tcm/PrescriptionOrderLists.php @@ -929,8 +929,9 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn $inList = implode(',', $deptIds); $diagTbl = (new Diagnosis())->getTable(); $adTbl = (new AdminDept())->getTable(); + $poRef = '`' . str_replace('`', '', $poTbl) . '`'; $query->whereRaw( - YejiStatsLogic::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poTbl, $diagTbl, $adTbl, $inList) + YejiStatsLogic::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poRef, $diagTbl, $adTbl, $inList) ); } } diff --git a/server/app/adminapi/logic/stats/YejiStatsLogic.php b/server/app/adminapi/logic/stats/YejiStatsLogic.php index f8f83664..d3670ea4 100755 --- a/server/app/adminapi/logic/stats/YejiStatsLogic.php +++ b/server/app/adminapi/logic/stats/YejiStatsLogic.php @@ -3426,7 +3426,6 @@ class YejiStatsLogic return; } $diagTable = self::tableWithPrefix('tcm_diagnosis'); - $adTable = self::tableWithPrefix('admin_dept'); if ($hasDept) { $ids = array_values(array_unique(array_filter(array_map('intval', $expandedDeptIds), static function (int $x): bool { return $x > 0; @@ -3437,16 +3436,9 @@ class YejiStatsLogic return; } $inList = implode(',', $ids); - $query->where(function ($q) use ($diagTable, $adTable, $inList) { - $q->whereExists( - "SELECT 1 FROM {$adTable} ad INNER JOIN {$diagTable} dg ON ad.admin_id = dg.assistant_id AND dg.delete_time IS NULL " - . "WHERE dg.id = o.diagnosis_id AND ad.dept_id IN ({$inList})" - ); - $q->whereExists( - "SELECT 1 FROM {$adTable} adc WHERE adc.admin_id = o.creator_id AND adc.dept_id IN ({$inList})", - 'OR' - ); - }); + $diagTb = (new Diagnosis())->getTable(); + $adTb = (new AdminDept())->getTable(); + $query->whereRaw(self::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst('`o`', $diagTb, $adTb, $inList)); } if ($hasVis) { $ids = array_values(array_unique(array_filter(array_map('intval', $visibleAdminIds), static function (int $x): bool { @@ -4926,22 +4918,23 @@ class YejiStatsLogic * {@see aggregateListAlignedOrderMetricsByDept} 及 * {@see PrescriptionOrderLists::applyDoctorAssistantFilters} 中 assistant_dept_id 一致)。 * - * @param string $inListComma 已净化的 id 列表(仅数字与逗号) + * @param string $orderRefBackticked 主查询里业务订单表标识,须已加反引号:列表/Model 无别名时用 `` `zyt_tcm_prescription_order` ``;Db::name()->alias('o') 时用 `` `o` `` + * @param string $inListComma 已净化的 id 列表(仅数字与逗号) */ public static function sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst( - string $poTbl, + string $orderRefBackticked, string $diagTbl, string $adTbl, string $inListComma ): string { - $creatorInSubtree = "EXISTS (SELECT 1 FROM `{$adTbl}` adc WHERE adc.`admin_id` = `{$poTbl}`.`creator_id` AND adc.`dept_id` IN ({$inListComma}))"; + $creatorInSubtree = "EXISTS (SELECT 1 FROM `{$adTbl}` adc WHERE adc.`admin_id` = {$orderRefBackticked}.`creator_id` AND adc.`dept_id` IN ({$inListComma}))"; $assistantInSubtree = "EXISTS (SELECT 1 FROM `{$adTbl}` ad INNER JOIN `{$diagTbl}` dg ON ad.admin_id = dg.assistant_id AND dg.delete_time IS NULL " - . "WHERE dg.`id` = `{$poTbl}`.`diagnosis_id` AND ad.dept_id IN ({$inListComma}))"; + . "WHERE dg.`id` = {$orderRefBackticked}.`diagnosis_id` AND ad.dept_id IN ({$inListComma}))"; return '(' - . '((IFNULL(`' . $poTbl . '`.`creator_id`,0) > 0) AND (' . $creatorInSubtree . '))' + . '((IFNULL(' . $orderRefBackticked . '.`creator_id`,0) > 0) AND (' . $creatorInSubtree . '))' . ' OR ' - . '((IFNULL(`' . $poTbl . '`.`creator_id`,0) <= 0) AND (' . $assistantInSubtree . '))' + . '((IFNULL(' . $orderRefBackticked . '.`creator_id`,0) <= 0) AND (' . $assistantInSubtree . '))' . ')'; } @@ -4994,9 +4987,9 @@ class YejiStatsLogic } } - $poTbl = (new PrescriptionOrder())->getTable(); + $poRef = '`' . str_replace('`', '', (new PrescriptionOrder())->getTable()) . '`'; $diagTbl = (new Diagnosis())->getTable(); - $adTbl = (new AdminDept())->getTable(); + $adTbl = (new AdminDept())->getTable(); $tSubtree = DeptLogic::getSelfAndDescendantIds($targetRowDeptId); $tSubtree = array_values(array_filter(array_map('intval', $tSubtree), static fn (int $id): bool => $id > 0)); @@ -5006,7 +4999,7 @@ class YejiStatsLogic return; } $tIn = implode(',', $tSubtree); - $clauses = [self::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poTbl, $diagTbl, $adTbl, $tIn)]; + $clauses = [self::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poRef, $diagTbl, $adTbl, $tIn)]; foreach ($beaters as $b) { $bSubtree = DeptLogic::getSelfAndDescendantIds((int) $b); $bSubtree = array_values(array_filter(array_map('intval', $bSubtree), static fn (int $id): bool => $id > 0)); @@ -5014,7 +5007,7 @@ class YejiStatsLogic continue; } $bIn = implode(',', $bSubtree); - $clauses[] = 'NOT (' . self::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poTbl, $diagTbl, $adTbl, $bIn) . ')'; + $clauses[] = 'NOT (' . self::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poRef, $diagTbl, $adTbl, $bIn) . ')'; } $query->whereRaw('(' . implode(' AND ', $clauses) . ')'); } diff --git a/server/sql/1.9.20260511/add_tcm_prescription_order_creator_id_column.sql b/server/sql/1.9.20260511/add_tcm_prescription_order_creator_id_column.sql new file mode 100644 index 00000000..0f3c933b --- /dev/null +++ b/server/sql/1.9.20260511/add_tcm_prescription_order_creator_id_column.sql @@ -0,0 +1,8 @@ +-- 历史库若早于 2026_04_07 建表可能缺少 creator_id,会导致业绩看板等 SQL 报 Unknown column … creator_id +-- 执行前可先:SHOW COLUMNS FROM `zyt_tcm_prescription_order` LIKE 'creator_id'; +-- 若列已存在,本脚本会报错,跳过即可。 +ALTER TABLE `zyt_tcm_prescription_order` + ADD COLUMN `creator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建人管理员ID' AFTER `diagnosis_id`; + +-- 若需索引且尚未存在,可再执行(已存在会报错可忽略): +-- ALTER TABLE `zyt_tcm_prescription_order` ADD KEY `idx_creator_id` (`creator_id`);