Merge branch 'master' of https://gitee.com/v_cms/zyt
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
|
||||
namespace app\adminapi\controller\stats;
|
||||
|
||||
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
|
||||
use app\adminapi\logic\stats\YejiStatsLogic;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* 提成结算业绩(独立于业绩看板 yejiStats 接口)
|
||||
|
||||
*
|
||||
|
||||
* - GET stats.commissionSettlement/overview
|
||||
|
||||
* - GET stats.commissionSettlement/orderLines
|
||||
|
||||
* - GET stats.commissionSettlement/confirmStatus
|
||||
|
||||
* - POST stats.commissionSettlement/saveReconcile
|
||||
|
||||
* - POST stats.commissionSettlement/confirmFinalize
|
||||
|
||||
* - GET stats.commissionSettlement/deptOptions
|
||||
|
||||
* - GET stats.commissionSettlement/channelOptions
|
||||
|
||||
*/
|
||||
|
||||
class CommissionSettlementController extends BaseAdminController
|
||||
|
||||
{
|
||||
|
||||
public function overview()
|
||||
|
||||
{
|
||||
|
||||
@set_time_limit(120);
|
||||
|
||||
$params = $this->request->get();
|
||||
|
||||
|
||||
|
||||
return $this->data(YejiStatsLogic::commissionSettlementOverview($params, $this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function orderLines()
|
||||
|
||||
{
|
||||
|
||||
@set_time_limit(120);
|
||||
|
||||
|
||||
|
||||
return $this->data(YejiStatsLogic::commissionSettlementOrderLines($this->request->get(), $this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function confirmStatus()
|
||||
|
||||
{
|
||||
|
||||
return $this->data(YejiStatsLogic::commissionSettlementConfirmStatus($this->request->get(), $this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function saveReconcile()
|
||||
|
||||
{
|
||||
|
||||
return $this->data(YejiStatsLogic::commissionSettlementSaveReconcile($this->request->post(), $this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function confirmFinalize()
|
||||
|
||||
{
|
||||
|
||||
@set_time_limit(120);
|
||||
|
||||
|
||||
|
||||
return $this->data(YejiStatsLogic::commissionSettlementConfirmFinalize($this->request->post(), $this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function deptOptions()
|
||||
|
||||
{
|
||||
|
||||
return $this->data(YejiStatsLogic::deptOptions($this->adminId, $this->adminInfo));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function channelOptions()
|
||||
|
||||
{
|
||||
|
||||
return $this->data(YejiStatsLogic::channelOptions(false));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,16 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
{
|
||||
use HasDataScopeFilter;
|
||||
|
||||
/**
|
||||
* 诊单编辑/详情「挂号记录」Tab:按诊单 ID 拉全量挂号,不做医生/医助角色收窄与数据范围过滤。
|
||||
* 须同时传 patient_id(挂号表存的是诊单 id)与本开关,避免列表页被滥用拓宽可见范围。
|
||||
*/
|
||||
private function appointmentListsScopeRelaxedForDiagnosis(): bool
|
||||
{
|
||||
return (int) ($this->params['diag_scope_relax'] ?? 0) === 1
|
||||
&& (int) ($this->params['patient_id'] ?? 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据隔离:医生或医助(u.assistant_id = diag.assistant_id)命中可见集合;progress_board 场景放开(看板跨医生查看)
|
||||
*/
|
||||
@@ -28,6 +38,9 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
if ($progressBoard) {
|
||||
return;
|
||||
}
|
||||
if ($this->appointmentListsScopeRelaxedForDiagnosis()) {
|
||||
return;
|
||||
}
|
||||
if (!$this->dataScopeShouldApply()) {
|
||||
return;
|
||||
}
|
||||
@@ -128,7 +141,8 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
|
||||
// 面诊进度看板:可切换查看各医生挂号,不按当前账号角色收窄
|
||||
$progressBoard = (int) ($this->params['progress_board'] ?? 0) === 1;
|
||||
if (!$progressBoard) {
|
||||
$diagScopeRelax = $this->appointmentListsScopeRelaxedForDiagnosis();
|
||||
if (!$progressBoard && !$diagScopeRelax) {
|
||||
// 如果是医生角色(role_id=1),只显示挂自己号的预约
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
@@ -288,7 +302,8 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
|
||||
}
|
||||
|
||||
$progressBoard = (int) ($this->params['progress_board'] ?? 0) === 1;
|
||||
if (!$progressBoard) {
|
||||
$diagScopeRelax = $this->appointmentListsScopeRelaxedForDiagnosis();
|
||||
if (!$progressBoard && !$diagScopeRelax) {
|
||||
if (in_array(1, $roleIds)) {
|
||||
$query->where('a.doctor_id', $this->adminId);
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
|
||||
/**
|
||||
* 业绩看板:仅列出二中心复诊口径下的业务订单(须同时传 assistant_id、start_time、end_time;revisit_slot=0 为全部复诊分项合计)。
|
||||
* admin 维度按订单创建人 o.creator_id(与部门表复诊列、排行榜复诊列同口径)。
|
||||
*/
|
||||
private function applyYejiErCenterRevisitOrderFilter($query): void
|
||||
{
|
||||
@@ -138,7 +139,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
if ($t0 === false || $t1 === false) {
|
||||
return;
|
||||
}
|
||||
$ids = DeptLogic::listErCenterRevisitOrderIdsForAssistant(
|
||||
$ids = DeptLogic::listErCenterRevisitOrderIdsForCreator(
|
||||
$assistantId,
|
||||
$slot,
|
||||
(int) $t0,
|
||||
@@ -870,16 +871,23 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
$query->whereExists("SELECT 1 FROM {$rxTbl} rx WHERE rx.id = {$poTbl}.prescription_id AND rx.delete_time IS NULL AND rx.creator_id = {$doctorId}");
|
||||
}
|
||||
|
||||
/** 业绩看板入口(yeji_order_drawer=1)所有筛选统一按订单创建人;其它入口(处方订单列表 / 患者跟进等)保留旧口径(创建人 ∪ 诊单医助) */
|
||||
$yejiPanel = (int) ($this->params['yeji_order_drawer'] ?? 0) === 1;
|
||||
|
||||
if (isset($this->params['assistant_id']) && (int) $this->params['assistant_id'] > 0) {
|
||||
$assistantId = (int) $this->params['assistant_id'];
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->where(function ($q) use ($poTbl, $diagTbl, $assistantId) {
|
||||
$q->where('creator_id', $assistantId);
|
||||
$q->whereOrRaw(
|
||||
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$poTbl}`.`diagnosis_id`"
|
||||
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$assistantId})"
|
||||
);
|
||||
});
|
||||
if ($yejiPanel) {
|
||||
$query->where('creator_id', $assistantId);
|
||||
} else {
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->where(function ($q) use ($poTbl, $diagTbl, $assistantId) {
|
||||
$q->where('creator_id', $assistantId);
|
||||
$q->whereOrRaw(
|
||||
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$poTbl}`.`diagnosis_id`"
|
||||
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$assistantId})"
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->params['assistant_dept_id']) && $this->params['assistant_dept_id'] !== '' && (int) $this->params['assistant_dept_id'] > 0) {
|
||||
@@ -927,17 +935,31 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
return;
|
||||
}
|
||||
$inList = implode(',', $deptIds);
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$adTbl = (new AdminDept())->getTable();
|
||||
$poRef = '`' . str_replace('`', '', $poTbl) . '`';
|
||||
$query->whereRaw(
|
||||
YejiStatsLogic::sqlPrescriptionOrderListDeptSubtreeMatchCreatorFirst($poRef, $diagTbl, $adTbl, $inList)
|
||||
);
|
||||
if ($yejiPanel) {
|
||||
/** 业绩看板部门侧栏:仅订单创建人人事部门 ∈ 子树(与「合计业绩」/「接诊诊单」/「复诊」聚合同口径) */
|
||||
$query->whereExists(
|
||||
"SELECT 1 FROM `{$adTbl}` adc WHERE adc.`admin_id` = `{$poTbl}`.`creator_id` AND adc.`dept_id` IN ({$inList})"
|
||||
);
|
||||
} else {
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$query->where(function ($q) use ($poTbl, $diagTbl, $adTbl, $inList) {
|
||||
$q->whereExists(
|
||||
"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 ({$inList})"
|
||||
);
|
||||
$q->whereExists(
|
||||
"SELECT 1 FROM `{$adTbl}` adc WHERE adc.`admin_id` = `{$poTbl}`.`creator_id` AND adc.`dept_id` IN ({$inList})",
|
||||
'OR'
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 业绩看板侧栏:只保留「业绩归属医助」落在给定 admin_id 集合的订单(与 YejiStatsLogic::sqlPerformanceAttributionAdminExpr 一致)。
|
||||
* 业绩看板侧栏:只保留「业绩归属医助」落在给定 admin_id 集合的订单
|
||||
* (与 YejiStatsLogic::sqlPerformanceAttributionAdminExpr 一致——按订单创建人)。
|
||||
*
|
||||
* @param int[] $adminIds
|
||||
*/
|
||||
@@ -951,18 +973,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
|
||||
return;
|
||||
}
|
||||
$poTbl = (new PrescriptionOrder())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$rxTbl = (new Prescription())->getTable();
|
||||
$inList = implode(',', $adminIds);
|
||||
$query->whereRaw(
|
||||
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg "
|
||||
. "LEFT JOIN `{$rxTbl}` rx ON rx.`id` = `{$poTbl}`.`prescription_id` AND rx.`delete_time` IS NULL "
|
||||
. "WHERE dg.`id` = `{$poTbl}`.`diagnosis_id` AND dg.`delete_time` IS NULL AND `{$poTbl}`.`diagnosis_id` > 0 AND "
|
||||
. '(CASE WHEN dg.`assistant_id` > 0 THEN dg.`assistant_id` '
|
||||
. "WHEN `{$poTbl}`.`creator_id` > 0 AND (rx.`id` IS NULL OR NOT (`{$poTbl}`.`creator_id` <=> rx.`creator_id`)) THEN `{$poTbl}`.`creator_id` "
|
||||
. 'ELSE 0 END) IN (' . $inList . '))'
|
||||
);
|
||||
$query->whereIn('creator_id', $adminIds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -219,21 +219,24 @@ class DeptLogic extends BaseLogic
|
||||
}
|
||||
|
||||
return $q
|
||||
->field(['o.diagnosis_id', 'o.create_time', 'o.id', 'dg.assistant_id'])
|
||||
->field(['o.diagnosis_id', 'o.create_time', 'o.id', 'dg.assistant_id', 'o.creator_id'])
|
||||
->order(['o.diagnosis_id' => 'asc', 'o.create_time' => 'asc', 'o.id' => 'asc'])
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心子树:各部门复诊 rollup;同时返回按诊单医助聚合的分项(供医助排行榜)。
|
||||
* 二中心子树:各部门复诊 rollup(按订单创建人 creator_id 归属)。
|
||||
* 候选订单仍要求 dg.assistant_id > 0(保持「er-center 案例 = 有医助的诊单」的定义),
|
||||
* 但**复诊归属**改为订单创建人——leaf 部门归属取 creator_id 在二中心子树内的 canonical 部门,
|
||||
* 并产出 by_creator_slots 供医助排行榜复诊列复用,与诊金 / 接诊诊单口径完全一致。
|
||||
*
|
||||
* @param list<int> $subtreeDeptIds
|
||||
*
|
||||
* @return array{
|
||||
* totals: array<int, int>,
|
||||
* slots: array<int, array<int, int>>,
|
||||
* by_assistant_slots: array<int, array<int, int>>
|
||||
* by_creator_slots: array<int, array<int, int>>
|
||||
* }
|
||||
*/
|
||||
private static function computeErCenterRevisitFullPack(
|
||||
@@ -249,12 +252,12 @@ class DeptLogic extends BaseLogic
|
||||
$emptyTotals[$did] = 0;
|
||||
}
|
||||
if ($subtreeDeptIds === []) {
|
||||
return ['totals' => [], 'slots' => [], 'by_assistant_slots' => []];
|
||||
return ['totals' => [], 'slots' => [], 'by_creator_slots' => []];
|
||||
}
|
||||
$subtreeSet = array_fill_keys($subtreeDeptIds, true);
|
||||
$orderRows = self::fetchErCenterRevisitCandidateOrders($orderStartTs, $orderEndTs);
|
||||
if ($orderRows === []) {
|
||||
return ['totals' => $emptyTotals, 'slots' => $emptySlots, 'by_assistant_slots' => []];
|
||||
return ['totals' => $emptyTotals, 'slots' => $emptySlots, 'by_creator_slots' => []];
|
||||
}
|
||||
|
||||
$byPatient = [];
|
||||
@@ -266,29 +269,30 @@ class DeptLogic extends BaseLogic
|
||||
$byPatient[$pid][] = $r;
|
||||
}
|
||||
|
||||
$assistantNeed = [];
|
||||
$creatorNeed = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid > 0) {
|
||||
$assistantNeed[$aid] = true;
|
||||
$cid = (int) ($orders[$i]['creator_id'] ?? 0);
|
||||
if ($cid > 0) {
|
||||
$creatorNeed[$cid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$assistantIds = array_keys($assistantNeed);
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree($assistantIds, $subtreeSet);
|
||||
$creatorIds = array_keys($creatorNeed);
|
||||
/** 复用 buildAssistantCanonicalDeptInSubtree —— 该方法实际是 admin → 子树内 canonical 部门,与 admin 角色无关 */
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree($creatorIds, $subtreeSet);
|
||||
|
||||
/** @var array<int, array<int, int>> $leafByDeptSlot dept_id => [ slot => cnt ],slot≥2 */
|
||||
$leafByDeptSlot = [];
|
||||
/** @var array<int, array<int, int>> $byAssistantSlot */
|
||||
$byAssistantSlot = [];
|
||||
/** @var array<int, array<int, int>> $byCreatorSlot 复诊按订单创建人聚合(与诊金/接诊诊单口径一致) */
|
||||
$byCreatorSlot = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$slot = $i + 1;
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
$deptId = $canonicalDept[$aid] ?? null;
|
||||
$cid = (int) ($orders[$i]['creator_id'] ?? 0);
|
||||
$deptId = $canonicalDept[$cid] ?? null;
|
||||
if ($deptId === null || !isset($subtreeSet[$deptId])) {
|
||||
continue;
|
||||
}
|
||||
@@ -296,11 +300,11 @@ class DeptLogic extends BaseLogic
|
||||
$leafByDeptSlot[$deptId] = [];
|
||||
}
|
||||
$leafByDeptSlot[$deptId][$slot] = ($leafByDeptSlot[$deptId][$slot] ?? 0) + 1;
|
||||
if ($aid > 0) {
|
||||
if (!isset($byAssistantSlot[$aid])) {
|
||||
$byAssistantSlot[$aid] = [];
|
||||
if ($cid > 0) {
|
||||
if (!isset($byCreatorSlot[$cid])) {
|
||||
$byCreatorSlot[$cid] = [];
|
||||
}
|
||||
$byAssistantSlot[$aid][$slot] = ($byAssistantSlot[$aid][$slot] ?? 0) + 1;
|
||||
$byCreatorSlot[$cid][$slot] = ($byCreatorSlot[$cid][$slot] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,16 +317,16 @@ class DeptLogic extends BaseLogic
|
||||
$rollupTotals[$id] = array_sum($rollupSlots[$id] ?? []);
|
||||
}
|
||||
|
||||
foreach ($byAssistantSlot as $aid => $sm) {
|
||||
foreach ($byCreatorSlot as $cid => $sm) {
|
||||
if ($sm !== []) {
|
||||
ksort($byAssistantSlot[$aid], SORT_NUMERIC);
|
||||
ksort($byCreatorSlot[$cid], SORT_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'totals' => $rollupTotals,
|
||||
'slots' => $rollupSlots,
|
||||
'by_assistant_slots' => $byAssistantSlot,
|
||||
'by_creator_slots' => $byCreatorSlot,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -345,11 +349,11 @@ class DeptLogic extends BaseLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心子树内:各医助成交的复诊业务单笔数(合计 + 复诊2/3/…分项),口径与部门 rollup 同源。
|
||||
* 二中心子树复诊:按订单创建人 creator_id 聚合(与部门 rollup 同源,与诊金/接诊诊单口径一致)。
|
||||
*
|
||||
* @return array{totals: array<int, int>, slots: array<int, array<int, int>>}
|
||||
*/
|
||||
public static function getErCenterRevisitCountsByAssistant(?int $orderStartTs = null, ?int $orderEndTs = null): array
|
||||
public static function getErCenterRevisitCountsByCreator(?int $orderStartTs = null, ?int $orderEndTs = null): array
|
||||
{
|
||||
$erRoots = self::findErCenterRootDeptIds();
|
||||
$subtreeIds = self::unionErCenterSubtreeDeptIds($erRoots);
|
||||
@@ -357,42 +361,36 @@ class DeptLogic extends BaseLogic
|
||||
return ['totals' => [], 'slots' => []];
|
||||
}
|
||||
$pack = self::computeErCenterRevisitFullPack($subtreeIds, $orderStartTs, $orderEndTs);
|
||||
$by = $pack['by_assistant_slots'];
|
||||
$by = $pack['by_creator_slots'];
|
||||
$totals = [];
|
||||
$slots = [];
|
||||
foreach ($by as $aid => $slotMap) {
|
||||
$aid = (int) $aid;
|
||||
$totals[$aid] = (int) array_sum($slotMap);
|
||||
$slots[$aid] = $slotMap;
|
||||
foreach ($by as $cid => $slotMap) {
|
||||
$cid = (int) $cid;
|
||||
$totals[$cid] = (int) array_sum($slotMap);
|
||||
$slots[$cid] = $slotMap;
|
||||
}
|
||||
|
||||
return ['totals' => $totals, 'slots' => $slots];
|
||||
}
|
||||
|
||||
/**
|
||||
* 某医助在区间内、计入二中心复诊的业务订单 id(用于看板侧栏按复诊笔数下钻)。
|
||||
* 二中心子树复诊:列出某「订单创建人」在区间内、复诊序列(slot≥2)命中的业务订单 id(用于看板侧栏按复诊笔数下钻)。
|
||||
* $revisitSlot = 0 表示累计全部复诊(第 2 笔起);≥2 时仅该分项。
|
||||
*
|
||||
* @return list<int>
|
||||
*/
|
||||
public static function listErCenterRevisitOrderIdsForAssistant(
|
||||
int $assistantId,
|
||||
public static function listErCenterRevisitOrderIdsForCreator(
|
||||
int $creatorId,
|
||||
int $revisitSlot,
|
||||
int $orderStartTs,
|
||||
int $orderEndTs
|
||||
): array {
|
||||
if ($assistantId <= 0 || $orderStartTs <= 0 || $orderEndTs < $orderStartTs) {
|
||||
if ($creatorId <= 0 || $orderStartTs <= 0 || $orderEndTs < $orderStartTs) {
|
||||
return [];
|
||||
}
|
||||
if ($revisitSlot < 0 || $revisitSlot === 1) {
|
||||
return [];
|
||||
}
|
||||
$erRoots = self::findErCenterRootDeptIds();
|
||||
$subtreeIds = self::unionErCenterSubtreeDeptIds($erRoots);
|
||||
if ($subtreeIds === []) {
|
||||
return [];
|
||||
}
|
||||
$subtreeSet = array_fill_keys($subtreeIds, true);
|
||||
$orderRows = self::fetchErCenterRevisitCandidateOrders($orderStartTs, $orderEndTs);
|
||||
if ($orderRows === []) {
|
||||
return [];
|
||||
@@ -405,31 +403,16 @@ class DeptLogic extends BaseLogic
|
||||
}
|
||||
$byPatient[$pid][] = $r;
|
||||
}
|
||||
$assistantNeed = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid > 0) {
|
||||
$assistantNeed[$aid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree(array_keys($assistantNeed), $subtreeSet);
|
||||
$ids = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$slot = $i + 1;
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid !== $assistantId) {
|
||||
continue;
|
||||
}
|
||||
if ($revisitSlot > 0 && $slot !== $revisitSlot) {
|
||||
continue;
|
||||
}
|
||||
$dcan = $canonicalDept[$aid] ?? null;
|
||||
if ($dcan === null || !isset($subtreeSet[$dcan])) {
|
||||
$cid = (int) ($orders[$i]['creator_id'] ?? 0);
|
||||
if ($cid !== $creatorId) {
|
||||
continue;
|
||||
}
|
||||
$oid = (int) ($orders[$i]['id'] ?? 0);
|
||||
@@ -443,8 +426,8 @@ class DeptLogic extends BaseLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 某展示部门行(组织架构上含下级 rollup)内,二中心复诊按诊单医助拆解笔数。
|
||||
* 与看板行内「复诊」列口径一致:诊单下订单序列第 2 笔起;医助 canonical 部门须落在二中心子树且在该部门行的子树内。
|
||||
* 某展示部门行(组织架构上含下级 rollup)内,二中心复诊按**订单创建人**拆解笔数。
|
||||
* 与看板行内「复诊」列口径一致:订单序列第 2 笔起;创建人 canonical 部门须落在二中心子树且在该部门行的子树内。
|
||||
*
|
||||
* @return array{rows: list<array{admin_id: int, name: string, order_count: int}>}
|
||||
*/
|
||||
@@ -484,17 +467,17 @@ class DeptLogic extends BaseLogic
|
||||
}
|
||||
$byPatient[$pid][] = $r;
|
||||
}
|
||||
$assistantNeed = [];
|
||||
$creatorNeed = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid > 0) {
|
||||
$assistantNeed[$aid] = true;
|
||||
$cid = (int) ($orders[$i]['creator_id'] ?? 0);
|
||||
if ($cid > 0) {
|
||||
$creatorNeed[$cid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree(array_keys($assistantNeed), $erSubtreeSet);
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree(array_keys($creatorNeed), $erSubtreeSet);
|
||||
/** @var array<int, int> $counts */
|
||||
$counts = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
@@ -504,15 +487,15 @@ class DeptLogic extends BaseLogic
|
||||
if ($revisitSlot > 0 && $slot !== $revisitSlot) {
|
||||
continue;
|
||||
}
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid <= 0) {
|
||||
$cid = (int) ($orders[$i]['creator_id'] ?? 0);
|
||||
if ($cid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$canon = $canonicalDept[$aid] ?? null;
|
||||
$canon = $canonicalDept[$cid] ?? null;
|
||||
if ($canon === null || !isset($erSubtreeSet[$canon]) || !isset($descFlip[$canon])) {
|
||||
continue;
|
||||
}
|
||||
$counts[$aid] = ($counts[$aid] ?? 0) + 1;
|
||||
$counts[$cid] = ($counts[$cid] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
if ($counts === []) {
|
||||
@@ -527,10 +510,10 @@ class DeptLogic extends BaseLogic
|
||||
->column('name', 'id');
|
||||
}
|
||||
$rows = [];
|
||||
foreach ($counts as $aid => $cnt) {
|
||||
foreach ($counts as $cid => $cnt) {
|
||||
$rows[] = [
|
||||
'admin_id' => (int) $aid,
|
||||
'name' => (string) ($nameRows[$aid] ?? ('#' . $aid)),
|
||||
'admin_id' => (int) $cid,
|
||||
'name' => (string) ($nameRows[$cid] ?? ('#' . $cid)),
|
||||
'order_count' => (int) $cnt,
|
||||
];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user