Softhub软件下载站实战开发(五):分类模块实现

Softhub软件下载站实战开发(五):分类模块实现 💻🌳

本文我们将深入探讨Softhub软件下载站的分类模块设计与实现,这是构建软件下载站的核心功能之一。分类模块负责将海量软件进行有序组织,为用户提供清晰的浏览体验。

一、功能需求分析 🎯

分类模块需要满足以下核心需求:

  1. 分类管理:支持添加、编辑、删除软件分类
  2. 树形结构:支持两级分类(父/子分类)
  3. 分类关联:每个软件必须属于一个分类
  4. 数据验证:删除分类前需确保分类下无软件
  5. 图标支持:为每个分类设置个性化图标,基于fortawesome图标库
分类管理
添加分类
编辑分类
删除分类
分类列表
树形展示
多级嵌套
图标选择
删除校验

二、数据库设计 🗃️

分类表 ds_category 结构设计:

字段类型描述约束
idint(11)主键IDPRIMARY KEY
parent_idint(11)父分类IDDEFAULT 0
category_namevarchar(50)分类名称NOT NULL
iconvarchar(100)分类图标
sortint(11)排序NOT NULL
remarkvarchar(255)备注
created_byint(11)创建人NOT NULL
updated_byint(11)更新人NOT NULL
created_atdatetime创建时间NOT NULL
updated_atdatetime更新时间NOT NULL

三、后端实现 🚀

1. 核心逻辑设计

前端 控制器 服务层 数据访问层 请求操作分类 调用服务方法 执行数据库操作 返回结果 返回处理结果 返回响应 前端 控制器 服务层 数据访问层

2. 关键接口实现

添加分类逻辑:
func (s sDsCategory) Add(ctx context.Context, req *api.DsCategoryAddReq) error {
    // 检查分类名称是否已存在
    var category *model.DsCategoryInfo
    dao.DsCategory.Ctx(ctx).Where(dao.DsCategory.Columns().CategoryName, req.CategoryName).Scan(&category)
    if category != nil {
        return fmt.Errorf("分类%s已经存在", category.CategoryName)
    }

    // 检查父分类是否存在
    if req.ParentId != 0 {
        var parentCategory *model.DsCategoryInfo
        dao.DsCategory.Ctx(ctx).Where(dao.DsCategory.Columns().Id, req.ParentId).Scan(&parentCategory)
        if parentCategory == nil {
            return fmt.Errorf("父级分类不存在")
        }
        if parentCategory.ParentId != 0 {
            return fmt.Errorf("只能在顶级分类下添加子分类")
        }
    }

    // 插入新分类
    _, err := dao.DsCategory.Ctx(ctx).Insert(do.DsCategory{
        ParentId:     req.ParentId,
        CategoryName: req.CategoryName,
        Icon:         req.Icon,
        Sort:         req.Sort,
        Remark:       req.Remark,
        CreatedBy:    SystemS.Context().GetUserId(ctx),
        UpdatedBy:    SystemS.Context().GetUserId(ctx),
    })
    return err
}
删除分类逻辑:
func (s sDsCategory) Delete(ctx context.Context, id uint) error {
    // 检查分类下是否有软件
    var software *model.DsSoftwareInfo
    dao.DsSoftware.Ctx(ctx).Where(dao.DsSoftware.Columns().CategoryId+" = ?", id).Limit(1).Scan(&software)
    if software != nil {
        return fmt.Errorf("该分类下有软件,无法删除")
    }
    
    // 执行删除
    _, err := dao.DsCategory.Ctx(ctx).WherePri(id).Delete()
    return err
}

四、前端实现 🖥️

1. 树形表格展示

<el-table 
  :data="tableData.data" 
  row-key="id" 
  default-expand-all
  :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
  
  <el-table-column prop="categoryName" label="分类名称" />
  <el-table-column label="图标">
    <template #default="scope">
      <font-awesome-icon v-if="scope.row.icon" :icon="getIconObject(scope.row.icon)" />
    </template>
  </el-table-column>
  
  <el-table-column label="操作" width="240">
    <template #default="scope">
      <el-button 
        size="small" 
        text 
        type="success" 
        :disabled="!!scope.row.parentId"
        @click="onOpenAddChildCategory(scope.row)">
        新增子分类
      </el-button>
      <el-button 
        size="small" 
        text 
        type="primary" 
        @click="onOpenEditDsCategory(scope.row)">
        修改
      </el-button>
      <el-button 
        size="small" 
        text 
        type="danger" 
        @click="onRowDel(scope.row)">
        删除
      </el-button>
    </template>
  </el-table-column>
</el-table>

2. 图标选择器组件

参考Vue3 + Element Plus 实现强大的图标选择器组件

<el-form-item label="图标" prop="icon">
  <fs-icon-selector v-model="formData.icon" />
</el-form-item>

3. 添加/编辑分类对话框

<el-dialog v-model="isShowDialog">
  <el-form :model="formData" label-width="90px">
    <el-form-item label="上级分类" prop="parentId">
      <el-select v-model="formData.parentId" placeholder="请选择上级分类">
        <el-option 
          v-for="item in categoryTree" 
          :key="item.id" 
          :label="item.categoryName" 
          :value="item.id"
          :disabled="item.id === formData.id" />
      </el-select>
    </el-form-item>
    
    <el-form-item label="分类名称" prop="categoryName">
      <el-input v-model="formData.categoryName" />
    </el-form-item>
    
    <el-form-item label="图标" prop="icon">
      <fs-icon-selector v-model="formData.icon" />
    </el-form-item>
    
    <el-form-item label="排序" prop="sort">
      <el-input-number v-model="formData.sort" />
    </el-form-item>
    
    <el-form-item label="备注" prop="remark">
      <el-input v-model="formData.remark" />
    </el-form-item>
  </el-form>
</el-dialog>

五、实现效果展示 ✨


图1:分类管理页面 - 树形展示分类结构

image.png

图2:添加分类对话框 - 支持图标选择和父分类选择

六、关键问题解决 🛠️

  1. 树形结构性能优化

    • 后端一次性获取所有分类数据
    • 前端使用递归算法构建树形结构
  2. 图标选择器实现

    • 集成Font Awesome图标库
    • 实现图标搜索和分类功能
    • 支持三种风格图标(solid/regular/brands)

七、总结 📝

本文详细介绍了Softhub软件下载站分类模块的设计与实现,包括:

  1. 设计合理的数据库结构存储分类信息
  2. 实现后端分类管理的核心逻辑
  3. 开发前端树形分类展示界面
  4. 实现分类的增删改查功能

softhub系列往期文章

  1. Softhub软件下载站实战开发(一):项目总览
  2. Softhub软件下载站实战开发(二):项目基础框架搭建
  3. Softhub软件下载站实战开发(三):平台管理模块实战
  4. Softhub软件下载站实战开发(四):代码生成器设计与实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值