更新
This commit is contained in:
@@ -19,6 +19,7 @@ use app\common\model\auth\Admin;
|
||||
use app\common\model\auth\AdminDept;
|
||||
use app\common\model\dept\Dept;
|
||||
use app\common\service\DataScope\DataScopeService;
|
||||
use think\facade\Db;
|
||||
|
||||
|
||||
/**
|
||||
@@ -64,7 +65,9 @@ class DeptLogic extends BaseLogic
|
||||
if (!empty($lists)) {
|
||||
$pid = min(array_column($lists, 'pid'));
|
||||
}
|
||||
return self::getTree($lists, $pid);
|
||||
$tree = self::getTree($lists, $pid);
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,6 +144,557 @@ class DeptLogic extends BaseLogic
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 名称含「二中心」的部门 id(与业绩看板二中心规则一致)。
|
||||
*
|
||||
* @return list<int>
|
||||
*/
|
||||
private static function findErCenterRootDeptIds(): array
|
||||
{
|
||||
$rows = Dept::whereNull('delete_time')
|
||||
->field(['id', 'name'])
|
||||
->select()
|
||||
->toArray();
|
||||
$out = [];
|
||||
foreach ($rows as $r) {
|
||||
$name = (string) ($r['name'] ?? '');
|
||||
if ($name !== '' && mb_strpos($name, '二中心') !== false) {
|
||||
$out[] = (int) $r['id'];
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($out));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<int> $rootIds
|
||||
*
|
||||
* @return list<int>
|
||||
*/
|
||||
private static function unionErCenterSubtreeDeptIds(array $rootIds): array
|
||||
{
|
||||
$set = [];
|
||||
foreach ($rootIds as $rid) {
|
||||
$rid = (int) $rid;
|
||||
if ($rid <= 0) {
|
||||
continue;
|
||||
}
|
||||
foreach (self::getSelfAndDescendantIds($rid) as $id) {
|
||||
$set[(int) $id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 名称含「二中心」的部门及其全部下级 id(map),与业绩看板判定一致。
|
||||
*
|
||||
* @return array<int, true>
|
||||
*/
|
||||
public static function getErCenterSubtreeDeptIdSet(): array
|
||||
{
|
||||
$erRoots = self::findErCenterRootDeptIds();
|
||||
$subtreeIds = self::unionErCenterSubtreeDeptIds($erRoots);
|
||||
|
||||
return array_fill_keys($subtreeIds, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心复诊统计用的业务订单行(与 rollup 同源 SQL)。
|
||||
*
|
||||
* @return list<array{diagnosis_id: int, create_time: int, id: int, assistant_id: int}>
|
||||
*/
|
||||
private static function fetchErCenterRevisitCandidateOrders(?int $orderStartTs = null, ?int $orderEndTs = null): array
|
||||
{
|
||||
$q = Db::name('tcm_prescription_order')
|
||||
->alias('o')
|
||||
->join('tcm_diagnosis dg', 'dg.id = o.diagnosis_id AND dg.delete_time IS NULL', 'INNER')
|
||||
->whereNull('o.delete_time')
|
||||
->where('o.diagnosis_id', '>', 0)
|
||||
->where('dg.assistant_id', '>', 0)
|
||||
->whereRaw('NOT (o.fulfillment_status <=> ?)', [4]);
|
||||
if ($orderStartTs !== null && $orderEndTs !== null) {
|
||||
$q->where('o.create_time', 'between', [$orderStartTs, $orderEndTs]);
|
||||
}
|
||||
|
||||
return $q
|
||||
->field(['o.diagnosis_id', 'o.create_time', 'o.id', 'dg.assistant_id'])
|
||||
->order(['o.diagnosis_id' => 'asc', 'o.create_time' => 'asc', 'o.id' => 'asc'])
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心子树:各部门复诊 rollup;同时返回按诊单医助聚合的分项(供医助排行榜)。
|
||||
*
|
||||
* @param list<int> $subtreeDeptIds
|
||||
*
|
||||
* @return array{
|
||||
* totals: array<int, int>,
|
||||
* slots: array<int, array<int, int>>,
|
||||
* by_assistant_slots: array<int, array<int, int>>
|
||||
* }
|
||||
*/
|
||||
private static function computeErCenterRevisitFullPack(
|
||||
array $subtreeDeptIds,
|
||||
?int $orderStartTs = null,
|
||||
?int $orderEndTs = null
|
||||
): array {
|
||||
$emptySlots = [];
|
||||
$emptyTotals = [];
|
||||
foreach ($subtreeDeptIds as $did) {
|
||||
$did = (int) $did;
|
||||
$emptySlots[$did] = [];
|
||||
$emptyTotals[$did] = 0;
|
||||
}
|
||||
if ($subtreeDeptIds === []) {
|
||||
return ['totals' => [], 'slots' => [], 'by_assistant_slots' => []];
|
||||
}
|
||||
$subtreeSet = array_fill_keys($subtreeDeptIds, true);
|
||||
$orderRows = self::fetchErCenterRevisitCandidateOrders($orderStartTs, $orderEndTs);
|
||||
if ($orderRows === []) {
|
||||
return ['totals' => $emptyTotals, 'slots' => $emptySlots, 'by_assistant_slots' => []];
|
||||
}
|
||||
|
||||
$byPatient = [];
|
||||
foreach ($orderRows as $r) {
|
||||
$pid = (int) ($r['diagnosis_id'] ?? 0);
|
||||
if ($pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
$assistantIds = array_keys($assistantNeed);
|
||||
$canonicalDept = self::buildAssistantCanonicalDeptInSubtree($assistantIds, $subtreeSet);
|
||||
|
||||
/** @var array<int, array<int, int>> $leafByDeptSlot dept_id => [ slot => cnt ],slot≥2 */
|
||||
$leafByDeptSlot = [];
|
||||
/** @var array<int, array<int, int>> $byAssistantSlot */
|
||||
$byAssistantSlot = [];
|
||||
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;
|
||||
if ($deptId === null || !isset($subtreeSet[$deptId])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($leafByDeptSlot[$deptId])) {
|
||||
$leafByDeptSlot[$deptId] = [];
|
||||
}
|
||||
$leafByDeptSlot[$deptId][$slot] = ($leafByDeptSlot[$deptId][$slot] ?? 0) + 1;
|
||||
if ($aid > 0) {
|
||||
if (!isset($byAssistantSlot[$aid])) {
|
||||
$byAssistantSlot[$aid] = [];
|
||||
}
|
||||
$byAssistantSlot[$aid][$slot] = ($byAssistantSlot[$aid][$slot] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$childrenByPid = self::buildAllDeptChildrenByPid();
|
||||
$rollupSlots = self::rollupRevisitSlotsBySubtree($subtreeDeptIds, $subtreeSet, $childrenByPid, $leafByDeptSlot);
|
||||
$rollupTotals = [];
|
||||
foreach ($subtreeDeptIds as $id) {
|
||||
$id = (int) $id;
|
||||
$rollupTotals[$id] = array_sum($rollupSlots[$id] ?? []);
|
||||
}
|
||||
|
||||
foreach ($byAssistantSlot as $aid => $sm) {
|
||||
if ($sm !== []) {
|
||||
ksort($byAssistantSlot[$aid], SORT_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'totals' => $rollupTotals,
|
||||
'slots' => $rollupSlots,
|
||||
'by_assistant_slots' => $byAssistantSlot,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心子树:各部门复诊合计与分项(第 2 笔订单=复诊2…),供业绩看板等复用。
|
||||
* $orderStartTs/$orderEndTs 均非 null 时仅统计该 create_time 窗口内业务单(与看板区间一致);均为 null 时不限时间(慎用,数据量大)。
|
||||
*
|
||||
* @return array{totals: array<int, int>, slots: array<int, array<int, int>>}
|
||||
*/
|
||||
public static function getErCenterRevisitRollupIndexedByDept(?int $orderStartTs = null, ?int $orderEndTs = null): array
|
||||
{
|
||||
$erRoots = self::findErCenterRootDeptIds();
|
||||
$subtreeIds = self::unionErCenterSubtreeDeptIds($erRoots);
|
||||
if ($subtreeIds === []) {
|
||||
return ['totals' => [], 'slots' => []];
|
||||
}
|
||||
$pack = self::computeErCenterRevisitFullPack($subtreeIds, $orderStartTs, $orderEndTs);
|
||||
|
||||
return ['totals' => $pack['totals'], 'slots' => $pack['slots']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 二中心子树内:各医助成交的复诊业务单笔数(合计 + 复诊2/3/…分项),口径与部门 rollup 同源。
|
||||
*
|
||||
* @return array{totals: array<int, int>, slots: array<int, array<int, int>>}
|
||||
*/
|
||||
public static function getErCenterRevisitCountsByAssistant(?int $orderStartTs = null, ?int $orderEndTs = null): array
|
||||
{
|
||||
$erRoots = self::findErCenterRootDeptIds();
|
||||
$subtreeIds = self::unionErCenterSubtreeDeptIds($erRoots);
|
||||
if ($subtreeIds === []) {
|
||||
return ['totals' => [], 'slots' => []];
|
||||
}
|
||||
$pack = self::computeErCenterRevisitFullPack($subtreeIds, $orderStartTs, $orderEndTs);
|
||||
$by = $pack['by_assistant_slots'];
|
||||
$totals = [];
|
||||
$slots = [];
|
||||
foreach ($by as $aid => $slotMap) {
|
||||
$aid = (int) $aid;
|
||||
$totals[$aid] = (int) array_sum($slotMap);
|
||||
$slots[$aid] = $slotMap;
|
||||
}
|
||||
|
||||
return ['totals' => $totals, 'slots' => $slots];
|
||||
}
|
||||
|
||||
/**
|
||||
* 某医助在区间内、计入二中心复诊的业务订单 id(用于看板侧栏按复诊笔数下钻)。
|
||||
* $revisitSlot = 0 表示累计全部复诊(第 2 笔起);≥2 时仅该分项。
|
||||
*
|
||||
* @return list<int>
|
||||
*/
|
||||
public static function listErCenterRevisitOrderIdsForAssistant(
|
||||
int $assistantId,
|
||||
int $revisitSlot,
|
||||
int $orderStartTs,
|
||||
int $orderEndTs
|
||||
): array {
|
||||
if ($assistantId <= 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 [];
|
||||
}
|
||||
$byPatient = [];
|
||||
foreach ($orderRows as $r) {
|
||||
$pid = (int) ($r['diagnosis_id'] ?? 0);
|
||||
if ($pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$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])) {
|
||||
continue;
|
||||
}
|
||||
$oid = (int) ($orders[$i]['id'] ?? 0);
|
||||
if ($oid > 0) {
|
||||
$ids[$oid] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 某展示部门行(组织架构上含下级 rollup)内,二中心复诊按诊单医助拆解笔数。
|
||||
* 与看板行内「复诊」列口径一致:诊单下订单序列第 2 笔起;医助 canonical 部门须落在二中心子树且在该部门行的子树内。
|
||||
*
|
||||
* @return array{rows: list<array{admin_id: int, name: string, order_count: int}>}
|
||||
*/
|
||||
public static function getErCenterRevisitAssistantBreakdownForDept(
|
||||
int $rootDeptId,
|
||||
int $revisitSlot,
|
||||
int $orderStartTs,
|
||||
int $orderEndTs
|
||||
): array {
|
||||
if ($rootDeptId <= 0 || $orderStartTs <= 0 || $orderEndTs < $orderStartTs) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
if ($revisitSlot < 0 || $revisitSlot === 1) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
$erSubtreeSet = self::getErCenterSubtreeDeptIdSet();
|
||||
if ($erSubtreeSet === []) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
$descIds = self::getSelfAndDescendantIds($rootDeptId);
|
||||
$descFlip = [];
|
||||
foreach ($descIds as $did) {
|
||||
$did = (int) $did;
|
||||
if ($did > 0) {
|
||||
$descFlip[$did] = true;
|
||||
}
|
||||
}
|
||||
$orderRows = self::fetchErCenterRevisitCandidateOrders($orderStartTs, $orderEndTs);
|
||||
if ($orderRows === []) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
$byPatient = [];
|
||||
foreach ($orderRows as $r) {
|
||||
$pid = (int) ($r['diagnosis_id'] ?? 0);
|
||||
if ($pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$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), $erSubtreeSet);
|
||||
/** @var array<int, int> $counts */
|
||||
$counts = [];
|
||||
foreach ($byPatient as $orders) {
|
||||
$n = \count($orders);
|
||||
for ($i = 1; $i < $n; $i++) {
|
||||
$slot = $i + 1;
|
||||
if ($revisitSlot > 0 && $slot !== $revisitSlot) {
|
||||
continue;
|
||||
}
|
||||
$aid = (int) ($orders[$i]['assistant_id'] ?? 0);
|
||||
if ($aid <= 0) {
|
||||
continue;
|
||||
}
|
||||
$canon = $canonicalDept[$aid] ?? null;
|
||||
if ($canon === null || !isset($erSubtreeSet[$canon]) || !isset($descFlip[$canon])) {
|
||||
continue;
|
||||
}
|
||||
$counts[$aid] = ($counts[$aid] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
if ($counts === []) {
|
||||
return ['rows' => []];
|
||||
}
|
||||
$ids = array_keys($counts);
|
||||
$nameRows = [];
|
||||
if ($ids !== []) {
|
||||
$nameRows = Db::name('admin')
|
||||
->whereIn('id', $ids)
|
||||
->whereNull('delete_time')
|
||||
->column('name', 'id');
|
||||
}
|
||||
$rows = [];
|
||||
foreach ($counts as $aid => $cnt) {
|
||||
$rows[] = [
|
||||
'admin_id' => (int) $aid,
|
||||
'name' => (string) ($nameRows[$aid] ?? ('#' . $aid)),
|
||||
'order_count' => (int) $cnt,
|
||||
];
|
||||
}
|
||||
usort($rows, static function (array $a, array $b): int {
|
||||
if ($a['order_count'] !== $b['order_count']) {
|
||||
return $b['order_count'] <=> $a['order_count'];
|
||||
}
|
||||
|
||||
return strcmp((string) $a['name'], (string) $b['name']);
|
||||
});
|
||||
|
||||
return ['rows' => $rows];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, list<int>>
|
||||
*/
|
||||
private static function buildAllDeptChildrenByPid(): array
|
||||
{
|
||||
$rows = Dept::field(['id', 'pid'])->select()->toArray();
|
||||
$out = [];
|
||||
foreach ($rows as $r) {
|
||||
$pid = (int) ($r['pid'] ?? 0);
|
||||
$id = (int) ($r['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($out[$pid])) {
|
||||
$out[$pid] = [];
|
||||
}
|
||||
$out[$pid][] = $id;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<int, int>> $leafByDeptSlot
|
||||
*
|
||||
* @return array<int, array<int, int>> dept_id => [ slot => count ],已含下级汇总
|
||||
*/
|
||||
private static function rollupRevisitSlotsBySubtree(
|
||||
array $subtreeDeptIds,
|
||||
array $subtreeSet,
|
||||
array $childrenByPid,
|
||||
array $leafByDeptSlot
|
||||
): array {
|
||||
$memo = [];
|
||||
$dfs = static function (int $id) use (&$dfs, $childrenByPid, $leafByDeptSlot, $subtreeSet, &$memo): array {
|
||||
if (isset($memo[$id])) {
|
||||
return $memo[$id];
|
||||
}
|
||||
$acc = [];
|
||||
if (isset($leafByDeptSlot[$id])) {
|
||||
foreach ($leafByDeptSlot[$id] as $slot => $cnt) {
|
||||
$acc[(int) $slot] = (int) $cnt;
|
||||
}
|
||||
}
|
||||
foreach ($childrenByPid[$id] ?? [] as $cid) {
|
||||
$cid = (int) $cid;
|
||||
if (!isset($subtreeSet[$cid])) {
|
||||
continue;
|
||||
}
|
||||
$childAcc = $dfs($cid);
|
||||
foreach ($childAcc as $slot => $cnt) {
|
||||
$acc[$slot] = ($acc[$slot] ?? 0) + $cnt;
|
||||
}
|
||||
}
|
||||
if ($acc !== []) {
|
||||
ksort($acc, SORT_NUMERIC);
|
||||
}
|
||||
$memo[$id] = $acc;
|
||||
|
||||
return $acc;
|
||||
};
|
||||
|
||||
$out = [];
|
||||
foreach ($subtreeDeptIds as $id) {
|
||||
$id = (int) $id;
|
||||
$out[$id] = $dfs($id);
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<int> $assistantIds
|
||||
* @param array<int, true> $subtreeSet
|
||||
*
|
||||
* @return array<int, int> admin_id => dept_id
|
||||
*/
|
||||
private static function buildAssistantCanonicalDeptInSubtree(array $assistantIds, array $subtreeSet): array
|
||||
{
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $assistantIds), static function (int $v): bool {
|
||||
return $v > 0;
|
||||
})));
|
||||
if ($ids === []) {
|
||||
return [];
|
||||
}
|
||||
$subtreeIdList = array_keys($subtreeSet);
|
||||
$rows = AdminDept::whereIn('admin_id', $ids)
|
||||
->whereIn('dept_id', $subtreeIdList)
|
||||
->field(['admin_id', 'dept_id'])
|
||||
->select()
|
||||
->toArray();
|
||||
$candidates = [];
|
||||
foreach ($rows as $r) {
|
||||
$a = (int) ($r['admin_id'] ?? 0);
|
||||
$d = (int) ($r['dept_id'] ?? 0);
|
||||
if ($a > 0 && $d > 0) {
|
||||
$candidates[$a][] = $d;
|
||||
}
|
||||
}
|
||||
$depthMap = self::buildDeptIdDepthMap();
|
||||
$out = [];
|
||||
foreach ($candidates as $aid => $depts) {
|
||||
$best = null;
|
||||
$bestDepth = -1;
|
||||
foreach ($depts as $d) {
|
||||
$depth = (int) ($depthMap[$d] ?? 0);
|
||||
if (
|
||||
$best === null
|
||||
|| $depth > $bestDepth
|
||||
|| ($depth === $bestDepth && $d < (int) $best)
|
||||
) {
|
||||
$bestDepth = $depth;
|
||||
$best = $d;
|
||||
}
|
||||
}
|
||||
if ($best !== null) {
|
||||
$out[$aid] = (int) $best;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, int> dept_id => 从根层深度 0 起的层级
|
||||
*/
|
||||
private static function buildDeptIdDepthMap(): array
|
||||
{
|
||||
$rows = Dept::field(['id', 'pid'])->select()->toArray();
|
||||
$pidById = [];
|
||||
foreach ($rows as $r) {
|
||||
$pidById[(int) $r['id']] = (int) $r['pid'];
|
||||
}
|
||||
$depth = [];
|
||||
$getDepth = static function (int $id) use (&$getDepth, &$depth, $pidById): int {
|
||||
if (isset($depth[$id])) {
|
||||
return $depth[$id];
|
||||
}
|
||||
$p = (int) ($pidById[$id] ?? 0);
|
||||
$depth[$id] = $p > 0 ? $getDepth($p) + 1 : 0;
|
||||
|
||||
return $depth[$id];
|
||||
};
|
||||
foreach (array_keys($pidById) as $id) {
|
||||
$getDepth((int) $id);
|
||||
}
|
||||
|
||||
return $depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 列表树状结构
|
||||
* @param $array
|
||||
|
||||
Reference in New Issue
Block a user