This commit is contained in:
Your Name
2026-05-05 13:28:45 +08:00
parent 81b2808eaf
commit d6e105f912
19 changed files with 3730 additions and 267 deletions
@@ -19,6 +19,7 @@ use app\common\model\tcm\PrescriptionOrderPayOrder;
use app\common\model\ExpressTracking;
use app\common\service\gancao\GancaoScmRecipelService;
use think\facade\Config;
use think\facade\Db;
use think\db\Query;
class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface, ListsExtendInterface
@@ -98,10 +99,12 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$this->applyExpressCompanyFilter($query);
$this->applyExpressKeywordFilter($query);
$this->applySupplyModeFilter($query);
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
$query->where('creator_id', $this->adminId);
}
$this->applyCreatorOrOwnPrescriptionVisibility($query);
$this->applyDataScopeForPrescriptionOrder($query);
// 业绩看板侧栏等:不展示履约已取消(4),与 stats 业绩统计口径一致
if ((int) ($this->params['exclude_fulfillment_cancelled'] ?? 0) === 1) {
$query->where('fulfillment_status', '<>', 4);
}
}
/**
@@ -172,6 +175,30 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
}
}
/**
* 非「业务订单全量」角色:默认仅本人创建;若持有 viewOrdersForOwnPrescription 则包含关联处方开方人为本人的订单
*/
private function applyCreatorOrOwnPrescriptionVisibility($query): void
{
if (PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
return;
}
$adminId = (int) $this->adminId;
if (PrescriptionOrderLogic::canViewOrdersForOwnPrescription($this->adminInfo)) {
$poTbl = (new PrescriptionOrder())->getTable();
$rxTbl = (new Prescription())->getTable();
$query->where(function ($q) use ($poTbl, $rxTbl, $adminId) {
$q->where('creator_id', $adminId);
$q->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$rxTbl}` rx WHERE rx.`id` = `{$poTbl}`.`prescription_id`"
. " AND rx.`delete_time` IS NULL AND rx.`creator_id` = {$adminId})"
);
});
} else {
$query->where('creator_id', $adminId);
}
}
/**
* 数据隔离:创建者 ∈ 可见 admin,或 关联诊单医助 ∈ 可见 admin
*/
@@ -224,20 +251,23 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$this->applyPatientKeywordFilter($query);
if (PrescriptionOrderLogic::canViewOrderListStatsAllScope($this->adminInfo)) {
$this->applyDataScopeForPrescriptionOrder($query);
return $query;
} else {
$assistantRid = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
$myRoles = array_map('intval', $this->adminInfo['role_id'] ?? []);
if ($assistantRid > 0 && in_array($assistantRid, $myRoles, true)) {
$this->applyAssistantDiagnosisOnlyFilter($query);
$this->applyDataScopeForPrescriptionOrder($query);
} else {
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
$this->applyCreatorOrOwnPrescriptionVisibility($query);
}
$this->applyDataScopeForPrescriptionOrder($query);
}
}
$assistantRid = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
$myRoles = array_map('intval', $this->adminInfo['role_id'] ?? []);
if ($assistantRid > 0 && in_array($assistantRid, $myRoles, true)) {
$this->applyAssistantDiagnosisOnlyFilter($query);
$this->applyDataScopeForPrescriptionOrder($query);
return $query;
// 与列表 applyPermissionAndExtraFilters 一致:业绩侧栏传 exclude 时不统计已取消行
if ((int) ($this->params['exclude_fulfillment_cancelled'] ?? 0) === 1) {
$query->where('fulfillment_status', '<>', 4);
}
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
$query->where('creator_id', $this->adminId);
}
$this->applyDataScopeForPrescriptionOrder($query);
return $query;
}
@@ -400,7 +430,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$s = $this->computeListStatsForExtend();
$focus = $this->computeFocusCountsForExtend();
return [
$base = [
'deposit_min_amount' => PrescriptionOrderLogic::depositMinAmount(),
'gancao_scm_enabled' => GancaoScmRecipelService::isConfigured(),
'stats_order_amount' => $s['order_amount'],
@@ -422,6 +452,83 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
'focus_pending_ship_count' => $focus['pending_ship'],
'focus_risk_count' => $focus['risk'],
];
$yejiConsult = $this->computeYejiDrawerConsultCountIfRequested();
if ($yejiConsult !== null) {
$base['stats_yeji_consult_count'] = $yejiConsult;
}
return $base;
}
/**
* 业绩看板侧栏专用:约诊/接诊条数,与 YejiStatsLogic::applyConsultFiltersAlignedWithAppointmentLists 同口径
* doctor_appointment.status=3appointment_date 落入区间,有效医助 COALESCE(挂号.assistant_id,诊单.assistant_id))。
* 请求须带 yeji_order_drawer=1,且 assistant_id 或 assistant_dept_id 与起止时间有效。
*/
private function computeYejiDrawerConsultCountIfRequested(): ?int
{
if ((int) ($this->params['yeji_order_drawer'] ?? 0) !== 1) {
return null;
}
$assistantId = (int) ($this->params['assistant_id'] ?? 0);
$deptRootId = (int) ($this->params['assistant_dept_id'] ?? 0);
if ($assistantId <= 0 && $deptRootId <= 0) {
return null;
}
[$startDate, $endDate] = $this->resolveYejiConsultAppointmentDateRange();
if ($startDate === '' || $endDate === '') {
return null;
}
$eff = 'COALESCE(NULLIF(a.assistant_id, 0), NULLIF(u.assistant_id, 0))';
$query = Db::name('doctor_appointment')->alias('a')
->leftJoin('tcm_diagnosis u', 'a.patient_id = u.id')
->where('a.status', 3)
->whereBetween('a.appointment_date', [$startDate, $endDate])
->whereRaw('(u.id IS NULL OR u.delete_time IS NULL)');
if ($assistantId > 0) {
$query->whereRaw("({$eff}) = " . $assistantId);
} else {
$deptIds = DeptLogic::getSelfAndDescendantIds($deptRootId);
$deptIds = array_values(array_filter(array_map('intval', $deptIds), static function (int $id): bool {
return $id > 0;
}));
if ($deptIds === []) {
return 0;
}
$adTbl = (new AdminDept())->getTable();
$inList = implode(',', $deptIds);
$query->whereRaw(
"EXISTS (SELECT 1 FROM `{$adTbl}` ad WHERE ad.admin_id = {$eff} AND ad.dept_id IN ({$inList}))"
);
}
return (int) $query->count();
}
/**
* @return array{0: string, 1: string} Y-m-d
*/
private function resolveYejiConsultAppointmentDateRange(): array
{
$st = trim((string) ($this->params['start_time'] ?? ''));
$et = trim((string) ($this->params['end_time'] ?? ''));
if ($st === '' || $et === '') {
return ['', ''];
}
$t0 = strtotime($st);
$t1 = strtotime($et);
if ($t0 === false || $t1 === false) {
return ['', ''];
}
if ($t1 < $t0) {
$tmp = $t0;
$t0 = $t1;
$t1 = $tmp;
}
return [date('Y-m-d', $t0), date('Y-m-d', $t1)];
}
/**
@@ -551,6 +658,8 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$ar = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
if ($ar > 0 && in_array($ar, array_map('intval', $this->adminInfo['role_id'] ?? []), true)) {
$scope = 'assistant';
} elseif (PrescriptionOrderLogic::canViewOrdersForOwnPrescription($this->adminInfo)) {
$scope = 'own_rx';
}
}