更新
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\stats;
|
||||
|
||||
use app\adminapi\logic\dept\DeptLogic;
|
||||
use app\common\service\tcm\RevisitVisitSlotService;
|
||||
use think\facade\Db;
|
||||
|
||||
/** 新报表独立读取方法,保持原复诊率 Logic 源码及调用链不变。 */
|
||||
trait RevisitCohortDataSource
|
||||
{
|
||||
private static function fetchRollbackKeySet(int $startTs, int $endTs): array
|
||||
{
|
||||
$rows = Db::name('tcm_diagnosis_auto_assign_log')
|
||||
->where('rollback_time', '>=', $startTs)
|
||||
->where('rollback_time', '<=', $endTs)
|
||||
->where('diagnosis_id', '>', 0)
|
||||
->field(['diagnosis_id', 'rollback_time', 'rollback_admin_id'])
|
||||
->select()
|
||||
->toArray();
|
||||
$out = [];
|
||||
foreach ($rows as $r) {
|
||||
$out[RevisitRateCalculator::rollbackKey(
|
||||
(int) ($r['diagnosis_id'] ?? 0),
|
||||
(int) ($r['rollback_time'] ?? 0),
|
||||
(int) ($r['rollback_admin_id'] ?? 0)
|
||||
)] = true;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private static function iterateOrderSeqRows(array $diagIds, array $fields): \Generator
|
||||
{
|
||||
foreach (array_chunk($diagIds, 2000) as $chunk) {
|
||||
foreach (self::fetchOrderSeqRows($chunk, $fields) as $r) {
|
||||
yield $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function buildAssistantDeptIndex(array $adminIds): array
|
||||
{
|
||||
if ($adminIds === []) {
|
||||
return [[], []];
|
||||
}
|
||||
// admin_dept 为 (admin_id, dept_id) 联合主键、无自增 id;取最小 dept_id 作为归属部门保证确定性
|
||||
$relRows = Db::name('admin_dept')
|
||||
->whereIn('admin_id', $adminIds)
|
||||
->order(['admin_id' => 'asc', 'dept_id' => 'asc'])
|
||||
->field(['admin_id', 'dept_id'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$deptNames = Db::name('dept')
|
||||
->whereNull('delete_time')
|
||||
->column('name', 'id');
|
||||
|
||||
$canonical = [];
|
||||
foreach ($relRows as $r) {
|
||||
$aid = (int) ($r['admin_id'] ?? 0);
|
||||
$deptId = (int) ($r['dept_id'] ?? 0);
|
||||
if ($aid <= 0 || $deptId <= 0 || isset($canonical[$aid])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($deptNames[$deptId])) {
|
||||
continue;
|
||||
}
|
||||
$canonical[$aid] = $deptId;
|
||||
}
|
||||
|
||||
$names = [];
|
||||
foreach ($deptNames as $id => $name) {
|
||||
$names[(int) $id] = (string) $name;
|
||||
}
|
||||
|
||||
return [$canonical, $names];
|
||||
}
|
||||
|
||||
private static function resolveDeptFilterSet(mixed $raw): array
|
||||
{
|
||||
$erSet = DeptLogic::getErCenterSubtreeDeptIdSet();
|
||||
if ($erSet === []) {
|
||||
return [];
|
||||
}
|
||||
$deptFilterIds = self::parseDeptIds($raw);
|
||||
if ($deptFilterIds === []) {
|
||||
return $erSet;
|
||||
}
|
||||
$allowedRoots = [];
|
||||
foreach ($deptFilterIds as $id) {
|
||||
if (isset($erSet[$id])) {
|
||||
$allowedRoots[] = $id;
|
||||
}
|
||||
}
|
||||
if ($allowedRoots === []) {
|
||||
return [];
|
||||
}
|
||||
$expanded = self::expandDeptSubtreeSet($allowedRoots);
|
||||
$out = [];
|
||||
foreach ($expanded as $id => $_) {
|
||||
if (isset($erSet[$id])) {
|
||||
$out[$id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private static function parseDeptIds(mixed $raw): array
|
||||
{
|
||||
if ($raw === null || $raw === '' || $raw === []) {
|
||||
return [];
|
||||
}
|
||||
$list = \is_array($raw) ? $raw : explode(',', (string) $raw);
|
||||
|
||||
return array_values(array_unique(array_filter(
|
||||
array_map('intval', $list),
|
||||
static fn (int $v): bool => $v > 0
|
||||
)));
|
||||
}
|
||||
|
||||
private static function expandDeptSubtreeSet(array $deptIds): array
|
||||
{
|
||||
$rows = Db::name('dept')
|
||||
->whereNull('delete_time')
|
||||
->field(['id', 'pid'])
|
||||
->select()
|
||||
->toArray();
|
||||
$childrenByPid = [];
|
||||
foreach ($rows as $r) {
|
||||
$childrenByPid[(int) $r['pid']][] = (int) $r['id'];
|
||||
}
|
||||
|
||||
$set = [];
|
||||
$queue = $deptIds;
|
||||
while ($queue !== []) {
|
||||
$id = (int) array_shift($queue);
|
||||
if ($id <= 0 || isset($set[$id])) {
|
||||
continue;
|
||||
}
|
||||
$set[$id] = true;
|
||||
foreach ($childrenByPid[$id] ?? [] as $childId) {
|
||||
$queue[] = $childId;
|
||||
}
|
||||
}
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
private static function fetchRefundOrRejectDiagnosisSet(array $diagIds): array
|
||||
{
|
||||
if ($diagIds === []) {
|
||||
return [];
|
||||
}
|
||||
$out = [];
|
||||
foreach (array_chunk($diagIds, 2000) as $chunk) {
|
||||
$ids = Db::name('tcm_prescription_order')
|
||||
->whereIn('diagnosis_id', $chunk)
|
||||
->whereNull('delete_time')
|
||||
->whereIn('fulfillment_status', [9, 10])
|
||||
->group('diagnosis_id')
|
||||
->column('diagnosis_id');
|
||||
foreach ($ids as $id) {
|
||||
$out[(int) $id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private static function fetchOrderSeqRows(array $diagIds, array $fields): array
|
||||
{
|
||||
// 实现已搬至 RevisitVisitSlotService(诊次口径单点维护),此处保留委托以减少 diff
|
||||
return RevisitVisitSlotService::fetchOrderSeqRows($diagIds, $fields);
|
||||
}
|
||||
|
||||
private static function fetchRevisitSlotStartOffsetMap(array $diagIds): array
|
||||
{
|
||||
// 实现已搬至 RevisitVisitSlotService(诊次口径单点维护),此处保留委托以减少 diff
|
||||
return RevisitVisitSlotService::fetchRevisitSlotStartOffsetMap($diagIds);
|
||||
}
|
||||
|
||||
private static function fetchDiagnosisInfo(array $diagIds): array
|
||||
{
|
||||
if ($diagIds === []) {
|
||||
return [];
|
||||
}
|
||||
$rows = Db::name('tcm_diagnosis')
|
||||
->whereIn('id', $diagIds)
|
||||
->field(['id', 'patient_name', 'phone'])
|
||||
->select()
|
||||
->toArray();
|
||||
$out = [];
|
||||
foreach ($rows as $r) {
|
||||
$out[(int) $r['id']] = [
|
||||
'patient_name' => trim((string) ($r['patient_name'] ?? '')),
|
||||
'phone' => trim((string) ($r['phone'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private static function cohortDeptOptions(): array
|
||||
{
|
||||
$erSet = DeptLogic::getErCenterSubtreeDeptIdSet();
|
||||
if ($erSet === []) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
$rows = Db::name('dept')
|
||||
->whereNull('delete_time')
|
||||
->whereIn('id', array_keys($erSet))
|
||||
->field(['id', 'pid', 'name'])
|
||||
->order('sort', 'desc')
|
||||
->order('id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return [
|
||||
'rows' => array_map(static fn (array $r): array => [
|
||||
'id' => (int) $r['id'],
|
||||
'pid' => (int) $r['pid'],
|
||||
'name' => (string) $r['name'],
|
||||
], $rows),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user