where($conditions); // 按排序字段排序 $resources = $query->orderBy('sort')->orderBy('id')->get(); // var_dump($resources->count()); // 转换为数组 $resourceList = []; foreach ($resources as $resource) { $resourceList[] = (array) $resource; } // 构建树状结构 return $this->buildTree($resourceList); } /** * 构建树状结构 * * @param array $resources 资源列表 * @param int $parentId 父级ID * @return array */ private function buildTree(array $resources, int $parentId = 0): array { $tree = []; foreach ($resources as $resource) { if ($resource['parent_id'] == $parentId) { // 递归获取子节点 $children = $this->buildTree($resources, $resource['id']); // 如果有子节点,则添加到children字段 if (!empty($children)) { $resource['children'] = $children; } $tree[] = $resource; } } return $tree; } /** * 使用引用方式构建树(性能优化版) * * @param array $conditions 筛选条件 * @return array */ public function getFullResourceTreeOptimized($table = 'resources', array $conditions = []): array { // 查询所有资源数据 $query = Db::table($table)->where($conditions); // 按排序字段排序 $resources = $query->orderBy('sort')->orderBy('id')->get(); // 构建ID映射和引用关系 $resourceMap = []; $tree = []; // 初始化所有节点 foreach ($resources as $resource) { $resourceArray = (array) $resource; $resourceMap[$resourceArray['id']] = $resourceArray; } // 构建父子关系 foreach ($resourceMap as $id => &$node) { if ($node['parent_id'] == 0) { // 根节点 $tree[] = &$node; } else { // 子节点 if (isset($resourceMap[$node['parent_id']])) { if (!isset($resourceMap[$node['parent_id']]['children'])) { $resourceMap[$node['parent_id']]['children'] = []; } $resourceMap[$node['parent_id']]['children'][] = &$node; } else { // 父节点不存在,作为根节点处理 $tree[] = &$node; } } } unset($node); return $tree; } /** * 获取扁平化的资源列表 * * @param array $conditions 筛选条件 * @return array */ public function getResourceList($table = 'resources', array $conditions = []): array { $query = Db::table($table)->where($conditions); // 按排序字段排序 $resources = $query->orderBy('sort')->orderBy('id')->get(); // 转换为数组 $resourceList = []; foreach ($resources as $resource) { $resourceList[] = (array) $resource; } return $resourceList; } /** * 递归插入资源树 */ private function insertResourceTree($table, $tree, $parentId, $keys = []) { $keys = ['system_id','name','desc','type','code','parent_id','url','icon','open_type','link', 'is_hide','is_hide_tab','no_auth','is_home','instance','keep_alive','sort','status']; foreach ($tree as $item) { // 保存子节点 $children = $item['children'] ?? []; // 过滤字段 $filteredItem = []; foreach ($item as $k => $v) { if (in_array($k, $keys)) { $filteredItem[$k] = $v; } } // 设置parent_id $filteredItem['parent_id'] = $parentId; // 插入并获取新ID $newId = Db::table($table)->insertGetId($filteredItem); echo "插入节点: {$filteredItem['name']}, 新ID: $newId\n"; // 递归处理子节点 if (!empty($children)) { $this->insertResourceTree($table, $children, $newId, $keys); } } } public function do(string $from = 'resources_20250916_bak', string $to = 'resources_yuanshi', array $where = []) { try { // 开启事务 Db::beginTransaction(); // 查询迁移资源的树状结果集 $list = $this->getFullResourceTreeOptimized($from, $where); // 入库字段 $keys = ['system_id','name','desc','type','code','parent_id','url','icon','open_type','link', 'is_hide','is_hide_tab','no_auth','is_home','instance','keep_alive','sort','status']; // 使用递归处理树结构 $this->insertResourceTree($to, $list, 0, $keys); // 提交事务 Db::commit(); echo "数据插入成功"; } catch (\Exception $e) { // 回滚事务 Db::rollBack(); echo "数据插入失败: " . $e->getMessage() . " 在文件 " . $e->getFile() . " 第 " . $e->getLine() . " 行"; } } }