前面几篇我们讲了软件管理相关实现,本篇我们实现后台管理最后一个功能,软件收藏集
在当今数字化时代,软件资源呈现爆炸式增长。用户面对海量软件时,常常会遇到几个核心痛点:
收藏集(Resource Set)功能的引入,正是为了解决这些痛点。它就像数字世界的"收藏夹",但比传统收藏功能更强大、更系统化。在Softhub平台中,收藏集不仅是简单的软件列表,更是一个完整的资源组织系统。
收藏集允许用户将相关软件组织在一起形成主题合集。例如:
这种组织方式实现了多维度的资源聚合。
我们设计了完整的RESTful API接口:
端点 | 方法 | 描述 | 参数 |
---|---|---|---|
/dsResourceSet |
GET | 获取收藏集列表 | 分页、搜索条件 |
/dsResourceSet/add |
POST | 创建新收藏集 | 名称、图标等 |
/dsResourceSet/edit |
PUT | 修改收藏集 | ID、新数据 |
/dsResourceSet/del |
DELETE | 删除收藏集 | ID |
/dsResourceSetRel/softwareList |
GET | 获取收藏集软件列表 | 收藏集ID |
/dsResourceSetRel/addSoftware |
POST | 添加软件到收藏集 | 收藏集ID、软件ID数组 |
/dsResourceSetRel/removeSoftware |
DELETE | 从收藏集移除软件 | 收藏集ID、软件ID |
type IDsResourceSet interface {
List(ctx context.Context, req *api.DsResourceSetListReq) (total interface{}, res []*model.DsResourceSetInfo, err error)
Add(ctx context.Context, req *api.DsResourceSetAddReq) (err error)
Edit(ctx context.Context, req *api.DsResourceSetEditReq) (err error)
Delete(ctx context.Context, id uint) (err error)
BatchDelete(ctx context.Context, ids []uint) (err error)
GetById(ctx context.Context, id uint) (res *model.DsResourceSetInfo, err error)
ClientList(ctx context.Context, req *clientApi.DsResourceSetListReq) (total interface{}, res []*model.DsResourceSetInfo, err error)
}
type IDsSoftwareResource interface {
List(ctx context.Context, req *api.DsSoftwareResourceListReq) (total interface{}, res []*model.DsSoftwareResourceInfo, err error)
Add(ctx context.Context, req *api.DsSoftwareResourceAddReq) (err error)
Edit(ctx context.Context, req *api.DsSoftwareResourceEditReq) (err error)
Delete(ctx context.Context, id interface{}) (err error)
BatchDelete(ctx context.Context, ids []interface{}) (err error)
GetById(ctx context.Context, id interface{}) (res *model.DsSoftwareResourceInfo, err error)
AddCount(ctx context.Context, resourceId interface{}) (count uint, err error)
SwitchDefault(ctx context.Context, req *api.DsSoftwareResourceSwitchDefaultReq) (err error)
InitChunkUpload(ctx context.Context, req *api.ChunkInitReq) (res *api.ChunkInitRes, err error)
UploadChunk(ctx context.Context, req *api.ChunkUploadReq) (res *api.ChunkUploadRes, err error)
MergeChunks(ctx context.Context, req *api.ChunkMergeReq) (res *api.ChunkMergeRes, err error)
}
func (s sDsResourceSet) List(ctx context.Context, req *api.DsResourceSetListReq) (total interface{}, dsResourceSetList []*model.DsResourceSetInfo, err error) {
err = g.Try(ctx, func(ctx context.Context) {
m := dao.DsResourceSet.Ctx(ctx)
columns := dao.DsResourceSet.Columns()
if req.Name != "" {
m = m.Where(fmt.Sprintf("%s like ?", columns.Name), "%"+req.Name+"%")
}
total, err = m.Count()
liberr.ErrIsNil(ctx, err, "获取资源集管理列表失败")
orderBy := req.OrderBy
if orderBy == "" {
orderBy = "created_at desc"
}
// 使用LEFT JOIN统计软件数量
err = m.Fields(fmt.Sprintf("%s.*, COUNT(DISTINCT rel.software_id) as software_count", dao.DsResourceSet.Table())).
LeftJoin("ds_resource_set_rel rel", fmt.Sprintf("%s.id = rel.set_id", dao.DsResourceSet.Table())).
Group(fmt.Sprintf("%s.id", dao.DsResourceSet.Table())).
Page(req.PageNum, req.PageSize).
Order(orderBy).
Scan(&dsResourceSetList)
liberr.ErrIsNil(ctx, err, "获取资源集管理列表失败")
})
return
}
func (s sDsResourceSet) Add(ctx context.Context, req *api.DsResourceSetAddReq) (err error) {
err = g.Try(ctx, func(ctx context.Context) {
// 查询是否已经存在
// add
_, err = dao.DsResourceSet.Ctx(ctx).Insert(do.DsResourceSet{
Name: req.Name, // 资源集名称
Icon: req.Icon, // 图标
Description: req.Description, // 资源描述
Remark: req.Remark, // 备注
CreatedBy: SystemS.Context().GetUserId(ctx),
UpdatedBy: SystemS.Context().GetUserId(ctx),
})
liberr.ErrIsNil(ctx, err, "新增资源集管理失败")
})
return
}
查询
新增
删除
-
{{ scope.row.softwareCount || 0 }}
修改
软件管理
删除
代码实现
当前资源集下的软件
添加软件
移除
搜索
重置
// 获取所有软件列表(带搜索和分页)
const getAllSoftwareList = () => {
state.addLoading = true;
const params = {
...state.allSoftwareParam,
softwareName: state.searchKeyword || undefined
};
getDsSoftwareList(params)
.then(res => {
state.allSoftwareList = processBigIntIds(res.data.dsSoftwareList || []);
state.allSoftwareTotal = res.data.total || 0;
})
.finally(() => {
state.addLoading = false;
});
};
// 添加选中软件到收藏集
const onAddSoftware = () => {
if (state.selectedSoftwareIds.length === 0) {
ElMessage.warning('请选择要添加的软件');
return;
}
state.adding = true;
const softwareIds = state.selectedSoftwareIds.map(id => toBigIntString(id));
addSoftwareToResourceSet({
setId: state.currentSetId,
softwareIds: softwareIds
})
.then(() => {
ElMessage.success('添加软件成功');
state.isShowAddDialog = false;
getCurrentSoftwareList();
})
.finally(() => {
state.adding = false;
});
};
softhub系列往期文章