Files
zyt/server/app/adminapi/logic/stats/AssistantPerformanceLogic.php
T
2026-10-15 11:03:54 +08:00

123 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\adminapi\logic\stats;
use think\facade\Db;
class AssistantPerformanceLogic
{
/** 履约完成 */
private const FULFILLMENT_COMPLETED = 3;
/**
* 「我的复诊接诊率」卡片(方案 §10 D1-h):仅返回当前登录医助本人的复诊接诊率行。
* 口径与复诊接诊率页一致(inherit_mode 取配置 project.revisit_rate.default_inherit_mode,默认 slot:
* 继承患者按继承时诊次从第 k+1 诊起计入分母);非二中心医助或当月无被指派患者时 row=null。
*
* @param string $month 统计月份 YYYY-MM,空 / 非法时回退当前月
*
* @return array{month:string,inherit_mode:string,slots:list<int>,in_scope:bool,row:array<string,mixed>|null}
*/
public static function revisitRate(int $adminId, string $month): array
{
$mode = (string) config('project.revisit_rate.default_inherit_mode', 'slot');
return RevisitRateLogic::assistantOverview($adminId, $month, $mode);
}
public static function overview(array $params, int $adminId, array $adminInfo): array
{
// 时间范围解析
$timeType = $params['time_type'] ?? 'month';
$today = date('Y-m-d');
switch ($timeType) {
case 'today':
$startDate = $today;
$endDate = $today;
break;
case 'yesterday':
$startDate = date('Y-m-d', strtotime('-1 day'));
$endDate = $startDate;
break;
case 'week':
$startDate = date('Y-m-d', strtotime('-6 days'));
$endDate = $today;
break;
case 'month':
$startDate = date('Y-m-d', strtotime('-29 days'));
$endDate = $today;
break;
case 'custom':
$startDate = $params['start_date'] ?? $today;
$endDate = $params['end_date'] ?? $today;
break;
default:
$startDate = date('Y-m-d', strtotime('-29 days'));
$endDate = $today;
}
$startTs = strtotime($startDate . ' 00:00:00');
$endTs = strtotime($endDate . ' 23:59:59');
// 查询当前医助创建的、履约已完成的处方业务订单
$baseQuery = Db::name('tcm_prescription_order')
->where('delete_time IS NULL')
->where('diagnosis_id', '>', 0)
->where('creator_id', $adminId)
->where('fulfillment_status', self::FULFILLMENT_COMPLETED)
->where('create_time', '>=', $startTs)
->where('create_time', '<=', $endTs);
// 业绩总额
$totalAmount = (clone $baseQuery)->sum('amount');
// 有效订单数
$totalCount = (clone $baseQuery)->count();
// 按日期分组的折线图数据
$dailyData = (clone $baseQuery)
->field("FROM_UNIXTIME(create_time, '%Y-%m-%d') as date_label, SUM(amount) as daily_amount, COUNT(*) as daily_count")
->group('date_label')
->order('date_label', 'asc')
->select()
->toArray();
// 补全日期范围内的空日期
$dateMap = [];
foreach ($dailyData as $row) {
$dateMap[$row['date_label']] = [
'amount' => round((float)$row['daily_amount'], 2),
'count' => (int)$row['daily_count'],
];
}
$dates = [];
$amounts = [];
$counts = [];
$cursor = strtotime($startDate);
$endCursor = strtotime($endDate);
while ($cursor <= $endCursor) {
$d = date('Y-m-d', $cursor);
$dates[] = substr($d, 5); // MM-DD
$amounts[] = $dateMap[$d]['amount'] ?? 0;
$counts[] = $dateMap[$d]['count'] ?? 0;
$cursor = strtotime('+1 day', $cursor);
}
return [
'date_range' => [$startDate, $endDate],
'summary' => [
'total_amount' => round((float)$totalAmount, 2),
'total_count' => (int)$totalCount,
],
'chart' => [
'dates' => $dates,
'amounts' => $amounts,
'counts' => $counts,
],
];
}
}