Sitelet https://github.com/rontian/UADownloader/blob/main/FILTER_INTEGRATION_SUMMARY.md
Skip to content

Latest commit

 

History

History
448 lines (358 loc) · 12.1 KB

File metadata and controls

448 lines (358 loc) · 12.1 KB

过滤器系统集成总结

实现概览

完成状态

✅ Phase 11: 过滤器系统 - 全部完成(10/10任务)

代码统计

  • 新增文件: 7个(703行)
  • 修改文件: 1个(PackageBatchDownloader.cs,+84行)
  • 总代码量: 787行

新增文件清单

1. 核心接口与数据模型(91行)

IPackageFilter.cs (69行)

  • 过滤器接口定义
  • 核心方法:
    • bool ShouldFilter(PackageInfo) - 判断是否过滤
    • string GetFilterReason(PackageInfo) - 获取过滤理由
    • Dictionary<string, FilterParamType> GetParamDefinitions() - 参数定义
    • void SetParams(Dictionary<string, object>) - 设置参数

FilteredRecord.cs (22行)

  • 过滤记录数据模型
  • 持久化到 FilteredPackages.json

2. 过滤器管理(131行)

FilterManager.cs (131行)

  • 管理激活的过滤器列表
  • 核心方法:
    • bool ShouldFilter(package, out filterName, out filterReason) - 遍历所有过滤器
    • AddFilter(filter) / RemoveFilter(filter) - 过滤器CRUD
    • GetFilteredCount() - 获取过滤计数
  • 自动持久化过滤记录到 FilteredPackages.json

3. 过滤器实现(169行)

DownloadedFilter.cs (97行)

  • 功能: 跳过已存在于 downloaded.json 的相同版本资源包
  • 参数: 无
  • 逻辑:
    var cached = _cachedDownloadedList.packages.Find(p => p.id == package.id);
    return cached != null && package.version == cached.version;

SizeFilter.cs (72行)

  • 功能: 跳过大于指定大小的资源包
  • 参数: maxSizeMB (int, 默认500MB)
  • 逻辑: package.size > maxSizeBytes

4. 注册表与UI(266行)

FilterRegistry.cs (51行)

  • 过滤器工厂注册表
  • 方法:
    • CreateFilter(typeName, exportPath) - 工厂方法
    • GetAllAvailableFilters(exportPath) - 获取所有可用过滤器

FilterSelectionWindow.cs (215行)

  • 过滤器选择弹窗
  • UI流程:
    1. 显示可用过滤器列表(带描述)
    2. 单选过滤器
    3. 输入参数(支持String/Int/Float/Bool)
    4. 返回配置好的过滤器实例

主窗口集成修改

PackageBatchDownloader.cs (8处修改,+84行)

1. 命名空间引用(Line 11)

using UADownloader.Filters;

2. 字段声明(Line 56-58)

private FilterManager _filterManager;
private int _filteredCount;
private bool _filterFoldout = true;

3. 初始化(Line 67-71)

if (!string.IsNullOrEmpty(_exportPath))
{
    _filterManager = new FilterManager(_exportPath);
}

4. UI布局(Line 88)

DrawFilterSection();  // 在导出设置下方,概览上方

5. 过滤器UI区域(Line 223-274,+52行)

private void DrawFilterSection()
{
    // 可折叠区域
    _filterFoldout = EditorGUILayout.Foldout(_filterFoldout, "过滤器设置", ...);
    
    // [+ 添加过滤器] 按钮
    if (GUILayout.Button("+ 添加过滤器", ...))
    {
        FilterSelectionWindow.ShowWindow(_exportPath, filter => {
            _filterManager?.AddFilter(filter);
            Repaint();
        });
    }
    
    // 显示激活的过滤器列表
    foreach (var filter in activeFilters)
    {
        // ✓ 名称 (参数) 描述 [×]
        // [×] 删除按钮
    }
}

6. 概览统计(Line 128, 135)

int filteredCount = _filterManager?.GetFilteredCount() ?? 0;
int remainingCount = totalCount - downloadedCount - failedCount - filteredCount;

EditorGUILayout.LabelField($"已过滤: {filteredCount}", GUILayout.Width(150));

7. 过滤逻辑(Line 489-502,+15行)

// 在获取详情后,下载前
if (_filterManager != null && _filterManager.ShouldFilter(package, out string filterName, out string filterReason))
{
    Debug.Log($"[BatchDownloader] 已过滤: {package.name} - 过滤器:{filterName}, 理由:{filterReason}");
    
    // 标记为已下载(用户要求)
    if (!_downloadIndex.downloaded.Contains(package.id))
    {
        _downloadIndex.downloaded.Add(package.id);
    }
    
    _filteredCount++;
    SaveDownloadIndex();
    Repaint();
    continue;  // 跳过下载
}

8. 完成消息(Line 537)

_statusMessage = $"批量下载完成 | 成功:{_downloadIndex.downloaded.Count} | 失败:{_downloadIndex.failed.Count} | 跳过:{_skippedCount} | 过滤:{_filteredCount} | ...";

持久化文件

FilteredPackages.json (新增)

位置: 导出目录/FilteredPackages.json

格式:

{
  "records": [
    {
      "packageId": 12345,
      "packageName": "Asset Name",
      "version": "1.2.3",
      "filterName": "大文件过滤器",
      "filterReason": "文件过大 (800MB > 500MB)",
      "filteredTime": "2026-03-05T10:30:00+08:00"
    }
  ]
}

触发时机: 每次过滤成功时自动保存(FilterManager.ShouldFilter())

downloaded.json (已存在,DownloadedFilter依赖)

位置: 导出目录/downloaded.json

格式: 与 packages.json 相同

用途: DownloadedFilter读取此文件,比对version是否相同


用户操作流程

基本使用

  1. 设置导出目录 → FilterManager需要此路径
  2. 添加过滤器 → 点击"+ 添加过滤器"按钮
  3. 选择过滤器 → 在弹窗中选择并配置参数
  4. 查看过滤器 → 在"过滤器设置"区域查看激活的过滤器
  5. 开始下载 → 每个资源包会自动经过过滤检查
  6. 查看统计 → "概览"显示"已过滤"数量

过滤逻辑

StartBatchDownloadAsync()
  ↓
for each package:
  ↓
  FetchAssetDetailsAsync()  // 获取详情(size, version等)
  ↓
  FilterManager.ShouldFilter() → 遍历所有过滤器 → 第一个匹配的生效
  ↓ true(过滤)
  downloaded.Add(id) → 标记为已下载 → continue(跳过下载)
  ↓ false(不过滤)
  DownloadPackageAsync()  // 继续下载

技术要点

1. 命名空间处理

由于 PackageInfo 定义在 UADownloader 命名空间,所有过滤器接口和实现中使用完全限定名:

// IPackageFilter.cs (在UADownloader.Filters命名空间中)
bool ShouldFilter(UADownloader.PackageInfo package);

2. 过滤器匹配逻辑(OR)

FilterManager.ShouldFilter() 遍历所有激活的过滤器,任意一个返回true即过滤:

foreach (var filter in _activeFilters)
{
    if (filter.ShouldFilter(package))
    {
        filterName = filter.GetName();
        return true;  // 第一个匹配的生效
    }
}
return false;

3. 过滤后的处理

被过滤的资源包:

  • ✅ 标记为"已下载"(downloaded.Add(id))
  • ✅ 保存到 FilteredPackages.json
  • ✅ 跳过下载逻辑
  • ✅ 在资源包列表中显示绿色"✓"图标(与真实下载的项相同)

4. 参数类型系统

支持4种参数类型:

public enum FilterParamType
{
    String,  // 字符串输入框
    Int,     // 整数输入框
    Float,   // 浮点数输入框
    Bool     // 复选框
}

FilterSelectionWindow根据类型自动生成对应的UI控件。


扩展性设计

添加新过滤器的步骤

1. 创建过滤器类

// Assets/UADownloader/Editor/Scripts/Filters/CategoryFilter.cs
namespace UADownloader.Filters
{
    public class CategoryFilter : IPackageFilter
    {
        private string _targetCategory = "3D";
        
        public string GetName() => "类别过滤器";
        public string GetDescription() => "跳过指定类别的资源包";
        
        public bool ShouldFilter(UADownloader.PackageInfo package)
        {
            return package.category == _targetCategory;
        }
        
        public Dictionary<string, FilterParamType> GetParamDefinitions()
        {
            return new Dictionary<string, FilterParamType>
            {
                { "targetCategory", FilterParamType.String }
            };
        }
        
        public void SetParams(Dictionary<string, object> paramValues)
        {
            if (paramValues.ContainsKey("targetCategory"))
            {
                _targetCategory = paramValues["targetCategory"] as string;
            }
        }
        
        public Dictionary<string, object> GetParams()
        {
            return new Dictionary<string, object>
            {
                { "targetCategory", _targetCategory }
            };
        }
        
        public string GetFilterReason(UADownloader.PackageInfo package)
        {
            return $"类别匹配 (category={package.category})";
        }
        
        public void CacheFiltered(UADownloader.PackageInfo package) { }
    }
}

2. 注册到FilterRegistry

// FilterRegistry.cs - 在static构造函数中添加
static FilterRegistry()
{
    RegisterFilter("DownloadedFilter", exportPath => new DownloadedFilter(exportPath));
    RegisterFilter("SizeFilter", exportPath => new SizeFilter());
    RegisterFilter("CategoryFilter", exportPath => new CategoryFilter());  // 新增
}

3. 完成!

无需修改任何其他代码,新过滤器会自动出现在选择弹窗中。


验证清单

编译验证

  • Unity编译无错误
  • Unity编译无警告

功能验证

  • 过滤器选择弹窗正常显示
  • 参数输入正常工作(Int类型)
  • 过滤器列表正确显示(名称+参数+描述)
  • 删除过滤器正常工作
  • 下载时过滤逻辑生效
  • 过滤的项正确标记为"已下载"
  • FilteredPackages.json正确保存
  • 概览统计"已过滤"数量正确

日志验证

  • 过滤成功时输出:[BatchDownloader] 已过滤: XXX - 过滤器:YYY, 理由:ZZZ
  • 完成消息显示:过滤:N

已知限制

  1. OR逻辑: 多个过滤器是OR关系(任意一个匹配即过滤),不支持AND
  2. 不可区分: 被过滤的项与真实下载的项都标记为"已下载",无法区分
  3. 不可动态修改: 下载过程中无法修改过滤器,需取消后重新开始
  4. 只增不减: FilteredPackages.json不会自动清理历史记录

下一步建议

功能增强

  1. 添加更多过滤器:类别、发布者、日期、评分
  2. 过滤器启用/禁用开关(不删除)
  3. 过滤预览模式(显示将被过滤的列表)
  4. 过滤历史查看器

逻辑增强

  1. 支持AND/OR/NOT组合逻辑
  2. 区分"已下载"和"已过滤"的标记
  3. 过滤器优先级排序
  4. 自定义脚本过滤器

UI增强

  1. 过滤器拖拽排序
  2. 过滤器分组(内置/自定义)
  3. 过滤器预设(保存/加载配置)
  4. 实时过滤统计图表

文档清单

  • ✅ AGENTS.md - 项目规范(已更新过滤器部分)
  • ✅ FILTER_INTEGRATION_SUMMARY.md - 集成总结(本文件)
  • ✅ FILTER_TEST_GUIDE.md - 测试指南
  • 📄 README.md - 用户手册(建议更新)

提交信息建议

feat: 添加资源包过滤器系统

新增功能:
- 过滤器接口架构(IPackageFilter)
- 已下载过滤器(比对downloaded.json的version)
- 大文件过滤器(可配置maxSizeMB参数)
- 过滤器管理器(FilterManager)
- 过滤器注册表(FilterRegistry)
- 过滤器选择弹窗(参数输入支持)
- 主窗口集成(UI + 过滤逻辑)
- 过滤记录持久化(FilteredPackages.json)

UI变更:
- 在导出设置下方添加"过滤器设置"区域
- 概览显示"已过滤"统计
- 完成消息显示"过滤:N"

技术实现:
- 7个新文件(703行)
- PackageBatchDownloader.cs 8处修改(+84行)
- 命名空间隔离(UADownloader.Filters)
- 可扩展架构(工厂模式 + 注册表)

文件清单:
- IPackageFilter.cs (69行)
- FilteredRecord.cs (22行)
- FilterManager.cs (131行)
- DownloadedFilter.cs (97行)
- SizeFilter.cs (72行)
- FilterRegistry.cs (51行)
- FilterSelectionWindow.cs (215行)
- PackageBatchDownloader.cs (+84行)

文档:
- FILTER_INTEGRATION_SUMMARY.md - 集成总结
- FILTER_TEST_GUIDE.md - 测试指南

集成完成时间: 2026-03-05
总耗时: Phase 11(过滤器系统)
代码行数: 787行(新增703 + 修改84)
状态: ✅ 就绪,等待Unity编译和功能测试