home-icon-management-implementation-plan.md 6.5 KB

首页图标发布功能实现方案

项目概述

在后端管理页面首页增加"图标发布"菜单,用于管理首页轮播图和分类图标的上传。使用现有的文件上传组件,上传后保存文件ID并关联文件实体。

技术架构

1. 实体设计 (src/server/modules/home/home-icon.entity.ts)

// 首页图标实体 - 支持轮播图和分类图标
@Entity('home_icons')
export class HomeIcon {
  @PrimaryGeneratedColumn({ unsigned: true })
  id!: number;

  @Column({ name: 'title', type: 'varchar', length: 255, comment: '图标标题' })
  title!: string;

  @Column({ name: 'type', type: 'varchar', length: 20, comment: '图标类型: banner, category' })
  type!: string;

  @Column({ name: 'file_id', type: 'int', unsigned: true, comment: '关联文件ID' })
  fileId!: number;

  @ManyToOne(() => File)
  @JoinColumn({ name: 'file_id', referencedColumnName: 'id' })
  file!: File;

  @Column({ name: 'sort_order', type: 'int', default: 0, comment: '排序顺序' })
  sortOrder!: number;

  @Column({ name: 'is_enabled', type: 'tinyint', default: 1, comment: '是否启用: 0-禁用, 1-启用' })
  isEnabled!: number;

  @Column({ name: 'link_url', type: 'varchar', length: 512, nullable: true, comment: '链接地址' })
  linkUrl!: string | null;

  @Column({ name: 'description', type: 'text', nullable: true, comment: '描述信息' })
  description!: string | null;

  @CreateDateColumn({ name: 'created_at' })
  createdAt!: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt!: Date;
}

2. 服务实现 (src/server/modules/home/home-icon.service.ts)

import { GenericCrudService } from '@/server/utils/generic-crud.service';
import { HomeIcon } from './home-icon.entity';

export class HomeIconService extends GenericCrudService<HomeIcon> {
  constructor(dataSource: DataSource) {
    super(dataSource, HomeIcon);
  }

  async getBanners(): Promise<HomeIcon[]> {
    return this.getList(1, 100, undefined, undefined, {
      type: 'banner',
      isEnabled: 1
    });
  }

  async getCategoryIcons(): Promise<HomeIcon[]> {
    return this.getList(1, 100, undefined, undefined, {
      type: 'category',
      isEnabled: 1
    });
  }
}

3. API路由设计 (src/server/api/home-icons/index.ts)

使用通用CRUD路由创建标准RESTful API:

  • GET /api/v1/home-icons - 获取图标列表
  • POST /api/v1/home-icons - 创建新图标
  • GET /api/v1/home-icons/{id} - 获取单个图标
  • PUT /api/v1/home-icons/{id} - 更新图标
  • DELETE /api/v1/home-icons/{id} - 删除图标

4. 前端页面实现 (src/client/admin/pages/HomeIcons.tsx)

页面功能

  • 轮播图管理表格
  • 分类图标管理表格
  • 文件上传组件集成
  • 拖拽排序功能
  • 启用/禁用状态切换

主要组件结构

const HomeIconsPage: React.FC = () => {
  const [activeTab, setActiveTab] = useState<'banner' | 'category'>('banner');
  
  return (
    <PageContainer>
      <Tabs activeKey={activeTab} onChange={setActiveTab}>
        <TabPane tab="轮播图管理" key="banner">
          <BannerTable />
        </TabPane>
        <TabPane tab="分类图标管理" key="category">
          <CategoryIconTable />
        </TabPane>
      </Tabs>
    </PageContainer>
  );
};

5. 菜单和路由配置

菜单添加 (src/client/admin/menu.tsx)

{
  key: 'home-icons',
  label: '图标发布',
  icon: <PictureOutlined />,
  path: '/admin/home-icons'
}

路由添加 (src/client/admin/routes.tsx)

{
  path: 'home-icons',
  element: <HomeIconsPage />,
  errorElement: <ErrorPage />
}

文件上传集成方案

使用现有MinioUploader组件

const UploadSection: React.FC<{ type: 'banner' | 'category' }> = ({ type }) => {
  const handleUploadSuccess = (fileKey: string, fileUrl: string, file: File) => {
    // 创建新的图标记录
    createHomeIcon({
      title: file.name,
      type,
      fileId: extractFileIdFromKey(fileKey),
      sortOrder: 0,
      isEnabled: 1
    });
  };

  return (
    <MinioUploader
      uploadPath={`/home-icons/${type}`}
      accept="image/*"
      maxSize={5}
      onUploadSuccess={handleUploadSuccess}
      buttonText={`上传${type === 'banner' ? '轮播图' : '分类图标'}`}
    />
  );
};

数据库迁移脚本

CREATE TABLE `home_icons` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '' COMMENT '图标标题',
  `type` varchar(20) NOT NULL DEFAULT '' COMMENT '图标类型: banner, category',
  `file_id` int(11) unsigned NOT NULL COMMENT '关联文件ID',
  `sort_order` int(11) NOT NULL DEFAULT '0' COMMENT '排序顺序',
  `is_enabled` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用: 0-禁用, 1-启用',
  `link_url` varchar(512) DEFAULT NULL COMMENT '链接地址',
  `description` text COMMENT '描述信息',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_type_enabled` (`type`, `is_enabled`),
  KEY `idx_sort_order` (`sort_order`),
  KEY `idx_file_id` (`file_id`),
  CONSTRAINT `fk_home_icon_file` FOREIGN KEY (`file_id`) REFERENCES `file` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='首页图标管理表';

实施步骤

第一阶段:后端实现

  1. 创建实体类 HomeIcon
  2. 注册实体到数据源
  3. 创建服务类 HomeIconService
  4. 创建API路由

第二阶段:前端实现

  1. 创建管理页面 HomeIconsPage
  2. 集成文件上传组件
  3. 添加表格展示和操作功能
  4. 添加菜单项和路由

第三阶段:测试验证

  1. 测试文件上传功能
  2. 测试CRUD操作
  3. 测试文件关联
  4. 测试排序和状态切换

API接口文档

获取轮播图

GET /api/v1/home-icons?type=banner&isEnabled=1

获取分类图标

GET /api/v1/home-icons?type=category&isEnabled=1

### 创建图标

POST /api/v1/home-icons { "title": "首页轮播图1", "type": "banner", "fileId": 123, "sortOrder": 1, "isEnabled": 1, "linkUrl": "https://example.com", "description": "首页主banner" } ```

安全考虑

  • 使用认证中间件保护API
  • 验证文件ID存在性
  • 限制文件类型为图片
  • 设置合理的文件大小限制
  • 添加操作日志记录

性能优化

  • 为常用查询字段添加索引
  • 实现分页查询
  • 使用CDN加速图片访问
  • 添加缓存机制

错误处理

  • 文件不存在错误
  • 上传失败处理
  • 数据库操作异常
  • 权限验证失败