Compare commits

..

3 Commits

4 changed files with 40 additions and 15 deletions

View File

@@ -730,7 +730,10 @@ class Network {
);
}
async listUserCollections(username: string, page: number = 1): Promise<PageResponse<Collection>> {
async listUserCollections(
username: string,
page: number = 1,
): Promise<PageResponse<Collection>> {
return this._callApi(() =>
axios.get(`${this.apiBaseUrl}/collection/list`, {
params: { username, page },
@@ -776,10 +779,11 @@ class Network {
async searchUserCollections(
username: string,
keyword: string,
excludedRID?: number,
): Promise<Response<Collection[]>> {
return this._callApi(() =>
axios.get(`${this.apiBaseUrl}/collection/search`, {
params: { username, keyword },
params: { username, keyword, excludedRID },
}),
);
}

View File

@@ -195,14 +195,21 @@ func handleRemoveResourceFromCollection(c fiber.Ctx) error {
func handleSearchUserCollections(c fiber.Ctx) error {
keyword := c.Query("keyword", "")
if keyword == "" {
return model.NewRequestError("keyword is required")
}
// if keyword == "" {
// return model.NewRequestError("keyword is required")
// }
username := c.Query("username", "")
if username == "" {
return model.NewRequestError("username is required")
}
cols, err := service.SearchUserCollections(username, keyword)
excludedRIDStr := c.Query("excludedRID", "")
var excludedRID uint = 0
if excludedRIDStr != "" {
if rid, err := strconv.Atoi(excludedRIDStr); err == nil && rid > 0 {
excludedRID = uint(rid)
}
}
cols, err := service.SearchUserCollections(username, keyword, excludedRID)
if err != nil {
return err
}

View File

@@ -15,11 +15,11 @@ func CreateCollection(uid uint, title string, article string, images []uint) (mo
Article: article,
}
if err := tx.Create(collection).Error; err != nil {
if err := tx.Create(&collection).Error; err != nil {
return err
}
if err := tx.Model(collection).Association("Images").Replace(images); err != nil {
if err := tx.Model(&collection).Association("Images").Replace(images); err != nil {
return err
}
@@ -176,14 +176,27 @@ func ListCollectionResources(collectionID uint, page int, pageSize int) ([]*mode
}
// SearchUserCollections searches for collections by user ID and keyword limited to 10 results.
func SearchUserCollections(uid uint, keyword string) ([]*model.Collection, error) {
// excludedRID: if >0, only return collections not containing this resource.
func SearchUserCollections(uid uint, keyword string, excludedRID uint) ([]*model.Collection, error) {
var collections []*model.Collection
if err := db.
Model(&model.Collection{}).
query := db.Model(&model.Collection{}).
Where("user_id = ?", uid)
if keyword != "" {
query = query.Where("title LIKE ?", "%"+keyword+"%")
}
if excludedRID > 0 {
// Use LEFT JOIN with IS NULL for better performance
query = query.
Joins("LEFT JOIN collection_resources cr ON collections.id = cr.collection_id AND cr.resource_id = ?", excludedRID).
Where("cr.collection_id IS NULL")
}
if err := query.
Preload("Images").
Preload("Resources").
Where("user_id = ? AND title LIKE ?", uid, "%"+keyword+"%").
Limit(10).
Find(&collections).Error; err != nil {
return nil, err

View File

@@ -134,8 +134,9 @@ func ListCollectionResources(collectionID uint, page int) ([]*model.ResourceView
}
// Search user collections by keyword, limited to 10 results.
func SearchUserCollections(username string, keyword string) ([]*model.CollectionView, error) {
if username == "" || keyword == "" {
// excludedRID: if >0, only return collections not containing this resource.
func SearchUserCollections(username string, keyword string, excludedRID uint) ([]*model.CollectionView, error) {
if username == "" {
return nil, errors.New("invalid parameters")
}
user, err := dao.GetUserByUsername(username)
@@ -143,7 +144,7 @@ func SearchUserCollections(username string, keyword string) ([]*model.Collection
return nil, err
}
uid := user.ID
collections, err := dao.SearchUserCollections(uid, keyword)
collections, err := dao.SearchUserCollections(uid, keyword, excludedRID)
if err != nil {
return nil, err
}