mirror of https://gitee.com/answerdev/answer.git
Merge branch 'feat/backyard-search' into 'main'
Feat/backyard search See merge request opensource/answer!137
This commit is contained in:
commit
ee723d2bfc
23
docs/docs.go
23
docs/docs.go
|
@ -56,6 +56,12 @@ const docTemplate = `{
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "answer id or question title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -173,6 +179,12 @@ const docTemplate = `{
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id or title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -709,19 +721,12 @@ const docTemplate = `{
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "username",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "email",
|
||||
"name": "e_mail",
|
||||
"description": "search query: email, username or id:[id]",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"normal",
|
||||
"suspended",
|
||||
"deleted",
|
||||
"inactive"
|
||||
|
|
|
@ -44,6 +44,12 @@
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "answer id or question title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -161,6 +167,12 @@
|
|||
"description": "user status",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "question id or title",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -697,19 +709,12 @@
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "username",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "email",
|
||||
"name": "e_mail",
|
||||
"description": "search query: email, username or id:[id]",
|
||||
"name": "query",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"normal",
|
||||
"suspended",
|
||||
"deleted",
|
||||
"inactive"
|
||||
|
|
|
@ -1390,6 +1390,10 @@ paths:
|
|||
in: query
|
||||
name: status
|
||||
type: string
|
||||
- description: answer id or question title
|
||||
in: query
|
||||
name: query
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1463,6 +1467,10 @@ paths:
|
|||
in: query
|
||||
name: status
|
||||
type: string
|
||||
- description: question id or title
|
||||
in: query
|
||||
name: query
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
@ -1788,17 +1796,12 @@ paths:
|
|||
in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- description: username
|
||||
- description: 'search query: email, username or id:[id]'
|
||||
in: query
|
||||
name: username
|
||||
type: string
|
||||
- description: email
|
||||
in: query
|
||||
name: e_mail
|
||||
name: query
|
||||
type: string
|
||||
- description: user status
|
||||
enum:
|
||||
- normal
|
||||
- suspended
|
||||
- deleted
|
||||
- inactive
|
||||
|
|
|
@ -365,6 +365,7 @@ func (qc *QuestionController) UserCollectionList(ctx *gin.Context) {
|
|||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param status query string false "user status" Enums(available, closed, deleted)
|
||||
// @Param query query string false "question id or title"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/question/page [get]
|
||||
func (qc *QuestionController) CmsSearchList(ctx *gin.Context) {
|
||||
|
@ -390,6 +391,7 @@ func (qc *QuestionController) CmsSearchList(ctx *gin.Context) {
|
|||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param status query string false "user status" Enums(available,deleted)
|
||||
// @Param query query string false "answer id or question title"
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/admin/api/answer/page [get]
|
||||
func (qc *QuestionController) CmsSearchAnswerList(ctx *gin.Context) {
|
||||
|
|
|
@ -45,9 +45,8 @@ func (uc *UserBackyardController) UpdateUserStatus(ctx *gin.Context) {
|
|||
// @Produce json
|
||||
// @Param page query int false "page size"
|
||||
// @Param page_size query int false "page size"
|
||||
// @Param username query string false "username"
|
||||
// @Param e_mail query string false "email"
|
||||
// @Param status query string false "user status" Enums(normal, suspended, deleted, inactive)
|
||||
// @Param query query string false "search query: email, username or id:[id]"
|
||||
// @Param status query string false "user status" Enums(suspended, deleted, inactive)
|
||||
// @Success 200 {object} handler.RespBody{data=pager.PageModel{records=[]schema.GetUserPageResp}}
|
||||
// @Router /answer/admin/api/users/page [get]
|
||||
func (uc *UserBackyardController) GetUserPage(ctx *gin.Context) {
|
||||
|
|
|
@ -44,6 +44,7 @@ type CmsAnswerSearch struct {
|
|||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Status int `json:"-" form:"-"`
|
||||
StatusStr string `json:"status" form:"status"` //Status 1 Available 2 closed 10 Deleted
|
||||
Query string `validate:"omitempty,gt=0,lte=100" json:"query" form:"query" ` //Query string
|
||||
}
|
||||
|
||||
type AdminSetAnswerStatusRequest struct {
|
||||
|
|
|
@ -2,7 +2,10 @@ package repo
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -202,11 +205,16 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc
|
|||
}
|
||||
|
||||
func (ar *answerRepo) CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error) {
|
||||
var count int64
|
||||
var err error
|
||||
if search.Status == 0 {
|
||||
search.Status = 1
|
||||
}
|
||||
var (
|
||||
count int64
|
||||
err error
|
||||
session = ar.data.DB.Table([]string{entity.Answer{}.TableName(), "a"}).Select("a.*")
|
||||
)
|
||||
|
||||
session.Where(builder.Eq{
|
||||
"a.status": search.Status,
|
||||
})
|
||||
|
||||
rows := make([]*entity.Answer, 0)
|
||||
if search.Page > 0 {
|
||||
search.Page = search.Page - 1
|
||||
|
@ -216,11 +224,42 @@ func (ar *answerRepo) CmsSearchList(ctx context.Context, search *entity.CmsAnswe
|
|||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
}
|
||||
|
||||
// search by question title like or answer id
|
||||
if len(search.Query) > 0 {
|
||||
// check id search
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
|
||||
if strings.Contains(search.Query, "id:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "id:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.Join("LEFT", []string{entity.Question{}.TableName(), "q"}, "q.id = a.question_id")
|
||||
session.And(builder.Like{
|
||||
"q.title", search.Query,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
offset := search.Page * search.PageSize
|
||||
session := ar.data.DB.Where("")
|
||||
session = session.And("status =?", search.Status)
|
||||
session = session.OrderBy("updated_at desc")
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
session.
|
||||
OrderBy("a.updated_at desc").
|
||||
Limit(search.PageSize, offset)
|
||||
count, err = session.FindAndCount(&rows)
|
||||
if err != nil {
|
||||
return rows, count, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -2,7 +2,10 @@ package repo
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -225,8 +228,16 @@ func (qr *questionRepo) SearchList(ctx context.Context, search *schema.QuestionS
|
|||
}
|
||||
|
||||
func (qr *questionRepo) CmsSearchList(ctx context.Context, search *schema.CmsQuestionSearch) ([]*entity.Question, int64, error) {
|
||||
var count int64
|
||||
var err error
|
||||
var (
|
||||
count int64
|
||||
err error
|
||||
session = qr.data.DB.Table("question")
|
||||
)
|
||||
|
||||
session.Where(builder.Eq{
|
||||
"status": search.Status,
|
||||
})
|
||||
|
||||
rows := make([]*entity.Question, 0)
|
||||
if search.Page > 0 {
|
||||
search.Page = search.Page - 1
|
||||
|
@ -236,11 +247,40 @@ func (qr *questionRepo) CmsSearchList(ctx context.Context, search *schema.CmsQue
|
|||
if search.PageSize == 0 {
|
||||
search.PageSize = constant.Default_PageSize
|
||||
}
|
||||
|
||||
// search by question title like or question id
|
||||
if len(search.Query) > 0 {
|
||||
// check id search
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
if strings.Contains(search.Query, "id:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(search.Query, "id:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.And(builder.Like{
|
||||
"title", search.Query,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
offset := search.Page * search.PageSize
|
||||
session := qr.data.DB.Table("question")
|
||||
session = session.And("status =?", search.Status)
|
||||
session = session.OrderBy("updated_at desc")
|
||||
session = session.Limit(search.PageSize, offset)
|
||||
|
||||
session.OrderBy("updated_at desc").
|
||||
Limit(search.PageSize, offset)
|
||||
count, err = session.FindAndCount(&rows)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -3,7 +3,11 @@ package user
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/mail"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"xorm.io/builder"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -68,7 +72,7 @@ func (ur *userBackyardRepo) GetUserInfo(ctx context.Context, userID string) (use
|
|||
}
|
||||
|
||||
// GetUserPage get user page
|
||||
func (ur *userBackyardRepo) GetUserPage(ctx context.Context, page, pageSize int, user *entity.User) (users []*entity.User, total int64, err error) {
|
||||
func (ur *userBackyardRepo) GetUserPage(ctx context.Context, page, pageSize int, user *entity.User, query string) (users []*entity.User, total int64, err error) {
|
||||
users = make([]*entity.User, 0)
|
||||
session := ur.data.DB.NewSession()
|
||||
if user.Status == entity.UserStatusDeleted {
|
||||
|
@ -78,6 +82,40 @@ func (ur *userBackyardRepo) GetUserPage(ctx context.Context, page, pageSize int,
|
|||
} else {
|
||||
session.Desc("created_at")
|
||||
}
|
||||
|
||||
if len(query) > 0 {
|
||||
if email, e := mail.ParseAddress(query); e == nil {
|
||||
session.And(builder.Eq{"e_mail": email.Address})
|
||||
} else {
|
||||
var (
|
||||
idSearch = false
|
||||
id = ""
|
||||
)
|
||||
|
||||
if strings.Contains(query, "id:") {
|
||||
idSearch = true
|
||||
id = strings.TrimSpace(strings.TrimPrefix(query, "id:"))
|
||||
for _, r := range id {
|
||||
if !unicode.IsDigit(r) {
|
||||
idSearch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if idSearch {
|
||||
session.And(builder.Eq{
|
||||
"id": id,
|
||||
})
|
||||
} else {
|
||||
session.And(builder.Or(
|
||||
builder.Like{"username", query},
|
||||
builder.Like{"display_name", query},
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total, err = pager.Help(page, pageSize, &users, user, session)
|
||||
if err != nil {
|
||||
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
|
|
|
@ -26,10 +26,8 @@ type GetUserPageReq struct {
|
|||
Page int `validate:"omitempty,min=1" form:"page"`
|
||||
// page size
|
||||
PageSize int `validate:"omitempty,min=1" form:"page_size"`
|
||||
// username
|
||||
Username string `validate:"omitempty,gt=0,lte=50" form:"username"`
|
||||
// email
|
||||
EMail string `validate:"omitempty,gt=0,lte=100" form:"e_mail"`
|
||||
Query string `validate:"omitempty,gt=0,lte=100" form:"query"`
|
||||
// user status
|
||||
Status string `validate:"omitempty,oneof=suspended deleted inactive" form:"status"`
|
||||
}
|
||||
|
|
|
@ -171,6 +171,7 @@ type CmsQuestionSearch struct {
|
|||
PageSize int `json:"page_size" form:"page_size"` //Search page size
|
||||
Status int `json:"-" form:"-"`
|
||||
StatusStr string `json:"status" form:"status"` //Status 1 Available 2 closed 10 UserDeleted
|
||||
Query string `validate:"omitempty,gt=0,lte=100" json:"query" form:"query" ` //Query string
|
||||
}
|
||||
|
||||
type AdminSetQuestionStatusRequest struct {
|
||||
|
|
|
@ -42,6 +42,9 @@ func (as *AnswerCommon) SearchAnswered(ctx context.Context, userId, questionId s
|
|||
}
|
||||
|
||||
func (as *AnswerCommon) CmsSearchList(ctx context.Context, search *entity.CmsAnswerSearch) ([]*entity.Answer, int64, error) {
|
||||
if search.Status == 0 {
|
||||
search.Status = 1
|
||||
}
|
||||
return as.answerRepo.CmsSearchList(ctx, search)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
type UserBackyardRepo interface {
|
||||
UpdateUserStatus(ctx context.Context, userID string, userStatus, mailStatus int, email string) (err error)
|
||||
GetUserInfo(ctx context.Context, userID string) (user *entity.User, exist bool, err error)
|
||||
GetUserPage(ctx context.Context, page, pageSize int, user *entity.User) (users []*entity.User, total int64, err error)
|
||||
GetUserPage(ctx context.Context, page, pageSize int, user *entity.User, query string) (users []*entity.User, total int64, err error)
|
||||
}
|
||||
|
||||
// UserBackyardService user service
|
||||
|
@ -91,7 +91,7 @@ func (us *UserBackyardService) GetUserPage(ctx context.Context, req *schema.GetU
|
|||
user.Status = entity.UserStatusDeleted
|
||||
}
|
||||
|
||||
users, total, err := us.userRepo.GetUserPage(ctx, req.Page, req.PageSize, user)
|
||||
users, total, err := us.userRepo.GetUserPage(ctx, req.Page, req.PageSize, user, req.Query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue