1. public function lisonkk() {
    2. // 从哪一个节点开始的ID
    3. $this->refreshCount(285);
    4. }
    1. /**
    2. * 更新分类统计(一个方法到底)
    3. */
    4. public function refreshCount(?int $startId = null)
    5. {
    6. // ===== 1. 一次性加载所有数据 =====
    7. $categories = Db::name('aa')->field('id, pid')->select()->toArray();
    8. $childrenMap = [];
    9. $countMap = [];
    10. // 初始化 countMap
    11. foreach ($categories as $item) {
    12. $countMap[(int)$item['id']] = 0;
    13. }
    14. // 加载 CC 表统计(只在这里出现)
    15. $stats = Db::table('cc')
    16. ->field('aid, COUNT(*) AS total')
    17. ->group('aid')
    18. ->select()
    19. ->toArray();
    20. foreach ($stats as $row) {
    21. $aid = (int)$row['aid'];
    22. if (isset($countMap[$aid])) {
    23. $countMap[$aid] = (int)$row['total'];
    24. }
    25. }
    26. // 构建 childrenMap
    27. foreach ($categories as $item) {
    28. $pid = (int)$item['pid'];
    29. $id = (int)$item['id'];
    30. $childrenMap[$pid][] = $id;
    31. }
    32. // ===== 2. 确定起始节点 =====
    33. if ($startId !== null) {
    34. $targetIds = [(int)$startId];
    35. } else {
    36. $allIds = array_keys($countMap);
    37. $rootPids = array_diff(array_keys($childrenMap), $allIds);
    38. $targetIds = [];
    39. foreach ($rootPids as $pid) {
    40. foreach ($childrenMap[$pid] ?? [] as $id) {
    41. $targetIds[] = $id;
    42. }
    43. }
    44. }
    45. // ===== 3. 递归更新 =====
    46. foreach ($targetIds as $id) {
    47. $this->calcAndUpdate($id, $childrenMap, $countMap);
    48. }
    49. return '分类统计完成';
    50. }
    51. /**
    52. * 仅递归累加 + 逐条更新
    53. */
    54. private function calcAndUpdate(int $id, array &$childrenMap, array &$countMap): int
    55. {
    56. $total = $countMap[$id] ?? 0;
    57. foreach ($childrenMap[$id] ?? [] as $childId) {
    58. $total += $this->calcAndUpdate($childId, $childrenMap, $countMap);
    59. }
    60. Db::name('aa')
    61. ->where('id', $id)
    62. ->update([
    63. 'count' => $total
    64. ]);
    65. return $total;
    66. }