新增功能

This commit is contained in:
Your Name
2026-08-07 14:32:35 +08:00
parent 16d301f302
commit 58a7197d3e
383 changed files with 713 additions and 542 deletions
@@ -14,7 +14,7 @@ use think\facade\Db;
/**
* 一诊「医生看板」。
*
* 医生是最终展示维度;部门权限通过实际经手医助下推到挂号、诊单与业绩:
* 医生是最终展示维度;部门权限通过实际经手医助下推到预约、诊单与业绩:
* - 医生 SELF:只看本人医生数据,不限制经手医助;
* - 医助 SELF:只看本人经手患者关联的医生数据;
* - 组长/经理:只看数据范围内医助经手患者关联的医生数据;
@@ -79,7 +79,15 @@ class FirstVisitDoctorDashboardLogic
$doctorDeptNames,
$doctorStatus
);
$summary = self::buildSummary($rows);
// 支付单没有医生字段,当前数据中的低额支付单也未关联患者;挂号只能按创建人及权限范围汇总,
// 不能为了医生排行而将医助创建的支付单虚构分摊给某位医生。
$registrationCreatorIds = $doctorSelf ? [$adminId] : $assistantIds;
$registrationTotal = self::loadRegistrationTotal(
$range['start'],
$range['end'],
$registrationCreatorIds
);
$summary = self::buildSummary($rows, $registrationTotal);
$trend = self::buildAmountTrend($doctorIds, $assistantIds);
$selectedDeptName = $selectedDeptId > 0
@@ -108,7 +116,8 @@ class FirstVisitDoctorDashboardLogic
'selected_dept_name' => $selectedDeptName,
'selected_doctor_name' => $selectedDoctorName,
'doctor_count' => count($rows),
'appointment_rule' => '总挂号包含已预约、已取消、已完成和已过号;面诊取状态为已完成的挂号',
'registration_rule' => '总挂号按支付时间统计已支付且实收金额大于 0、低于 10 元的订单,每笔计 1 个,并按订单创建人及当前权限范围归属',
'appointment_rule' => '总预约包含已预约、已取消、已完成和已过号;面诊取状态为已完成的预约',
'performance_rule' => '诊单按订单创建时间统计,排除已取消、拒收、全额退款及部分退款,金额归属处方开方医生',
],
'filters' => [
@@ -122,7 +131,8 @@ class FirstVisitDoctorDashboardLogic
'conversion' => self::ranking($rows, 'receive_conversion_rate', 8),
],
'funnel' => [
['key' => 'appointment', 'label' => '挂号', 'value' => (int) $summary['appointment_total']],
['key' => 'registration', 'label' => '挂号', 'value' => (int) $summary['registration_total']],
['key' => 'appointment', 'label' => '预约', 'value' => (int) $summary['appointment_total']],
['key' => 'interview', 'label' => '面诊', 'value' => (int) $summary['interview_count']],
['key' => 'receive', 'label' => '接诊', 'value' => (int) $summary['order_count']],
['key' => 'deal', 'label' => '成交', 'value' => (int) $summary['order_count']],
@@ -327,7 +337,7 @@ class FirstVisitDoctorDashboardLogic
}
/** @param array<int,array<string,mixed>> $rows @return array<string,mixed> */
private static function buildSummary(array $rows): array
private static function buildSummary(array $rows, int $registrationTotal): array
{
$appointmentTotal = 0;
$interviewCount = 0;
@@ -345,6 +355,7 @@ class FirstVisitDoctorDashboardLogic
}
return [
'registration_total' => $registrationTotal,
'appointment_total' => $appointmentTotal,
'interview_count' => $interviewCount,
'order_count' => $orderCount,
@@ -361,6 +372,40 @@ class FirstVisitDoctorDashboardLogic
];
}
/**
* 新挂号口径:支付时间位于筛选区间、状态为已支付、0 < 实收金额 < 10 元。
* null 表示全部创建人,空数组表示当前权限范围没有可统计创建人。
*
* @param int[]|null $creatorIds
*/
private static function loadRegistrationTotal(
string $startDate,
string $endDate,
?array $creatorIds
): int {
if ($creatorIds === []) {
return 0;
}
$query = Db::name('order')
->whereNull('delete_time')
->where('status', 2)
->where('amount', '>', 0)
->where('amount', '<', 10)
->whereNotNull('payment_time')
->where('payment_time', '<>', '')
->whereBetweenTime(
'payment_time',
$startDate . ' 00:00:00',
$endDate . ' 23:59:59'
);
if ($creatorIds !== null) {
$query->whereIn('creator_id', $creatorIds);
}
return (int) $query->count();
}
/** @param array<int,array<string,mixed>> $rows @return array<int,array<string,mixed>> */
private static function ranking(array $rows, string $field, int $limit): array
{