Files
fdesk/app/common/utils/MigrationResources.php
T
2025-09-16 10:45:02 +08:00

194 lines
5.9 KiB
PHP

<?php
// app/service/ResourceService.php
namespace app\common\utils;
use support\Db;
class MigrationResources
{
/**
* 获取完整的资源树结构(不区分系统)
*
* @param array $conditions 筛选条件
* @return array
*/
public function getFullResourceTree($table = 'resources', array $conditions = []): array
{
// 查询所有资源数据
$query = Db::table($table)->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() . " 行";
}
}
}