You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

4.7 KiB

资源配置数据统一管理

概述

将分散在各组件中的资源类型、图标、样式等预设数据抽离到统一的配置文件 constants/resource.ts 中进行管理,提高代码的可维护性和复用性。

问题

之前的实现中,资源相关的配置数据散落在多个组件中:

  1. ProjectResourcePanel.tsx

    • 硬编码的素材类别数组 [{ key: 'character', label: '角色' }, ...]
    • 资源图标映射 resourceCategoryIcons
    • 容器样式计算函数 getResourceContainerClass
  2. RightSidebar.tsx

    • 资源标签的类型定义 type: 'character' | 'scene' | 'prop'
    • 图标映射 icons
    • 颜色映射 colors

这种分散的配置方式导致:

  • 代码重复
  • 维护困难
  • 不利于跨模块复用
  • 类型不一致

解决方案

1. 创建统一配置文件

文件路径: client/src/constants/resource.ts

内容包括:

  • 资源类型常量 (RESOURCE_TYPES)

    export const RESOURCE_TYPES = {
      CHARACTER: 'character',
      SCENE: 'scene',
      PROP: 'prop',
      FOOTAGE: 'footage',
      IMAGE: 'image',
      VIDEO: 'video',
      AUDIO: 'audio',
      OTHER: 'other',
    } as const;
    
  • 资源类别配置 (RESOURCE_CATEGORIES)

    export const RESOURCE_CATEGORIES: ResourceCategory[] = [
      { key: RESOURCE_TYPES.CHARACTER, label: '角色', icon: User },
      { key: RESOURCE_TYPES.SCENE, label: '场景', icon: MapPin },
      { key: RESOURCE_TYPES.PROP, label: '道具', icon: Package },
      { key: RESOURCE_TYPES.FOOTAGE, label: '实拍', icon: Camera },
    ];
    
  • 图标映射 (RESOURCE_CATEGORY_ICONS)

  • 样式计算函数 (getResourceContainerClass)

  • 工具函数 (getResourceIcon, getResourceCategoryLabel)

2. 更新导出文件

文件路径: client/src/constants/index.ts

export * from './routes';
export * from './config';
export * from './resource'; // 新增

3. 重构组件

ProjectResourcePanel.tsx

改动:

  1. 移除本地定义的 resourceCategoryIconsgetResourceContainerClass
  2. @/constants 导入配置
  3. 使用 RESOURCE_TYPES 常量替换硬编码字符串
  4. 使用 RESOURCE_CATEGORIES 替换内联数组
  5. 使用 RESOURCE_CATEGORY_ICONS 直接获取图标(避免 ESLint 错误)

示例:

// 之前
const [filterType, setFilterType] = useState<string>('character');

// 之后
const [filterType, setFilterType] = useState<string>(RESOURCE_TYPES.CHARACTER);

RightSidebar.tsx

改动:

  1. 移除本地的 icons 映射
  2. 导入 RESOURCE_TYPESgetResourceIcon
  3. 更新 ResourceTag 组件使用统一配置

示例:

// 之前
const icons = {
  character: User,
  scene: Map,
  prop: Package,
};

// 之后
import { RESOURCE_TYPES, getResourceIcon } from '@/constants';
const Icon = getResourceIcon(type);

变更文件清单

新增文件

  • client/src/constants/resource.ts

修改文件

  • client/src/constants/index.ts
  • client/src/components/features/project/ProjectResourcePanel.tsx
  • client/src/components/layout/RightSidebar.tsx

优势

  1. 集中管理:所有资源配置在一个文件中,便于维护和修改
  2. 类型安全:使用 TypeScript 的 const 断言确保类型安全
  3. 易于扩展:新增资源类型只需修改配置文件
  4. 减少重复:消除了组件间的代码重复
  5. 提高复用性:其他模块可轻松导入使用

后续优化建议

  1. 颜色配置统一:可以将 RightSidebar 中的颜色映射也移到配置文件
  2. 国际化支持:考虑将标签文本改为 i18n key
  3. 主题化:资源标签颜色可以关联到主题系统
  4. 验证函数:添加资源类型验证函数

问题修复

问题:ReferenceError: User is not defined

原因: 在重构 RightSidebar.tsx 时移除了 UserMapPackage 图标的导入,但 ImagePromptPanel 组件仍在使用这些图标。

解决:

  1. 重新导入 UserPackage
  2. Map 改为 MapPin(保持与配置文件一致)
// 修复前
import { ChevronLeft, ChevronRight, Image, RotateCw, Camera, Send, MapPin } from 'lucide-react';

// 修复后
import { ChevronLeft, ChevronRight, Image, RotateCw, Camera, Send, MapPin, User, Package } from 'lucide-react';

注意: ImagePromptPanel 组件中的图标是用于表单标签展示,与 ResourceTag 组件使用的图标不同,因此需要单独导入。

测试验证

  • 无 TypeScript 类型错误
  • 无 ESLint 错误
  • 无运行时错误
  • 组件功能正常
  • 图标显示正确

完成时间

2026-01-14