mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 23:41:12 +08:00
Go: add delete search (#14014)
### What problem does this PR solve? As title. ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -145,3 +145,18 @@ func (dao *SearchDAO) QueryByTenantIDAndID(tenantID string, searchID string) ([]
|
||||
err := DB.Where("tenant_id = ? AND id = ? AND status = ?", tenantID, searchID, "1").Find(&searches).Error
|
||||
return searches, err
|
||||
}
|
||||
|
||||
// DeleteByID deletes a search by ID (soft delete by setting status to "0")
|
||||
// Reference: Python common_service.py::delete_by_id
|
||||
func (dao *SearchDAO) DeleteByID(id string) error {
|
||||
return DB.Model(&entity.Search{}).Where("id = ?", id).Update("status", "0").Error
|
||||
}
|
||||
|
||||
// Accessible4Deletion checks if a search can be deleted by a specific user
|
||||
// Reference: Python search_service.py::accessible4deletion
|
||||
// Returns true if the search exists, is valid, and was created by the user
|
||||
func (dao *SearchDAO) Accessible4Deletion(searchID string, userID string) bool {
|
||||
var search entity.Search
|
||||
err := DB.Where("id = ? AND created_by = ? AND status = ?", searchID, userID, "1").First(&search).Error
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -251,3 +251,61 @@ func (h *SearchHandler) GetSearch(c *gin.Context) {
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteSearch delete a search app
|
||||
// @Summary Delete Search App
|
||||
// @Description Delete a search app by ID
|
||||
// @Tags search
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param search_id path string true "search app ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/searches/{search_id} [delete]
|
||||
func (h *SearchHandler) DeleteSearch(c *gin.Context) {
|
||||
// Get current user from context (same as Python current_user)
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
userID := user.ID
|
||||
|
||||
// Get search_id from path parameter (same as Python <search_id>)
|
||||
searchID := c.Param("search_id")
|
||||
if searchID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": common.CodeBadRequest,
|
||||
"data": nil,
|
||||
"message": "search_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete search with permission check
|
||||
err := h.searchService.DeleteSearch(userID, searchID)
|
||||
if err != nil {
|
||||
// Check if it's an authorization error
|
||||
if err.Error() == "no authorization" {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeAuthenticationError,
|
||||
"data": false,
|
||||
"message": "No authorization.",
|
||||
})
|
||||
return
|
||||
}
|
||||
// Delete failed error
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeDataError,
|
||||
"data": nil,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Return success response (same as Python get_json_result(data=True))
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeSuccess,
|
||||
"data": true,
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
searches.GET("", r.searchHandler.ListSearches)
|
||||
searches.POST("", r.searchHandler.CreateSearch)
|
||||
searches.GET("/:search_id", r.searchHandler.GetSearch)
|
||||
searches.DELETE("/:search_id", r.searchHandler.DeleteSearch)
|
||||
}
|
||||
|
||||
file := v1.Group("/files")
|
||||
|
||||
@@ -233,3 +233,20 @@ func (s *SearchService) GetSearchDetail(userID string, searchID string) (*entity
|
||||
|
||||
return search, nil
|
||||
}
|
||||
|
||||
// DeleteSearch deletes a search app by ID
|
||||
func (s *SearchService) DeleteSearch(userID string, searchID string) error {
|
||||
// Step 1: Check deletion permission (same as Python SearchService.accessible4deletion)
|
||||
// Python: cls.model.select().where(cls.model.id == search_id, cls.model.created_by == user_id, cls.model.status == StatusEnum.VALID.value).first()
|
||||
if !s.searchDAO.Accessible4Deletion(searchID, userID) {
|
||||
return fmt.Errorf("no authorization")
|
||||
}
|
||||
|
||||
// Step 2: Execute delete (same as Python SearchService.delete_by_id)
|
||||
// Python: cls.model.delete().where(cls.model.id == pid).execute()
|
||||
if err := s.searchDAO.DeleteByID(searchID); err != nil {
|
||||
return fmt.Errorf("failed to delete search App %s: %w", searchID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user