feat: add tags support
This commit is contained in:
parent
f51f4fd3eb
commit
8efd032ad3
@ -7,7 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type searchRequest struct {
|
type searchRequest struct {
|
||||||
Search string `form:"search" json:"search"`
|
Keyword string `form:"keyword" json:"keyword"`
|
||||||
|
Tag string `form:"tag" json:"tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
@ -27,13 +28,13 @@ func (h *handler) Search(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: pagination
|
// TODO: pagination
|
||||||
if req.Search == "" {
|
if req.Keyword == "" {
|
||||||
// TODO: query without LIKE
|
// TODO: query without LIKE
|
||||||
problems, status := h.problemService.QueryFuzz(req.Search, true, true)
|
problems, status := h.problemService.QueryFuzz(req.Keyword, req.Tag, true, true)
|
||||||
e.Pong(c, status, problems)
|
e.Pong(c, status, problems)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
problems, status := h.problemService.QueryFuzz(req.Search, true, true)
|
problems, status := h.problemService.QueryFuzz(req.Keyword, req.Tag, true, true)
|
||||||
e.Pong(c, status, problems)
|
e.Pong(c, status, problems)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,15 @@ import (
|
|||||||
"git.0x7f.app/WOJ/woj-server/internal/service/problem"
|
"git.0x7f.app/WOJ/woj-server/internal/service/problem"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/jackc/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type updateRequest struct {
|
type updateRequest struct {
|
||||||
Pid uint `form:"pid" json:"pid"`
|
Pid uint `form:"pid" json:"pid"`
|
||||||
Title string `form:"title" json:"title"`
|
Title string `form:"title" json:"title"`
|
||||||
Statement string `form:"statement" json:"statement"`
|
Statement string `form:"statement" json:"statement"`
|
||||||
IsEnabled bool `form:"is_enabled" json:"is_enabled"`
|
Tags []string `form:"tags" json:"tags"`
|
||||||
|
IsEnabled bool `form:"is_enabled" json:"is_enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
@ -21,10 +23,11 @@ type updateRequest struct {
|
|||||||
// @Tags problem,admin
|
// @Tags problem,admin
|
||||||
// @Accept application/x-www-form-urlencoded
|
// @Accept application/x-www-form-urlencoded
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param pid formData int false "problem id, 0 for create"
|
// @Param pid formData int false "problem id, 0 for create"
|
||||||
// @Param title formData string false "title"
|
// @Param title formData string false "title"
|
||||||
// @Param statement formData string false "statement"
|
// @Param statement formData string false "statement"
|
||||||
// @Param is_enabled formData bool false "is enabled"
|
// @Param tags formData []string false "tags"
|
||||||
|
// @Param is_enabled formData bool false "is enabled"
|
||||||
// @Response 200 {object} e.Response[model.Problem] "problem info without provider information"
|
// @Response 200 {object} e.Response[model.Problem] "problem info without provider information"
|
||||||
// @Security Authentication
|
// @Security Authentication
|
||||||
// @Router /v1/problem/update [post]
|
// @Router /v1/problem/update [post]
|
||||||
@ -60,6 +63,7 @@ func (h *handler) Update(c *gin.Context) {
|
|||||||
createData := &problem.CreateData{
|
createData := &problem.CreateData{
|
||||||
Title: req.Title,
|
Title: req.Title,
|
||||||
Statement: req.Statement,
|
Statement: req.Statement,
|
||||||
|
Tags: req.Tags,
|
||||||
ProviderID: uid,
|
ProviderID: uid,
|
||||||
IsEnabled: false,
|
IsEnabled: false,
|
||||||
}
|
}
|
||||||
@ -83,6 +87,11 @@ func (h *handler) Update(c *gin.Context) {
|
|||||||
// update problem
|
// update problem
|
||||||
p.Title = utils.If(req.Title != "", req.Title, p.Title)
|
p.Title = utils.If(req.Title != "", req.Title, p.Title)
|
||||||
p.Statement = utils.If(req.Statement != "", req.Statement, p.Statement)
|
p.Statement = utils.If(req.Statement != "", req.Statement, p.Statement)
|
||||||
|
if len(req.Tags) != 0 {
|
||||||
|
tags := pgtype.TextArray{}
|
||||||
|
_ = tags.Set(req.Tags)
|
||||||
|
p.Tags = tags
|
||||||
|
}
|
||||||
p.IsEnabled = req.IsEnabled
|
p.IsEnabled = req.IsEnabled
|
||||||
|
|
||||||
p, status = h.problemService.Update(p)
|
p, status = h.problemService.Update(p)
|
||||||
|
@ -7,11 +7,12 @@ import (
|
|||||||
|
|
||||||
type Problem struct {
|
type Problem struct {
|
||||||
gorm.Model `json:"meta"`
|
gorm.Model `json:"meta"`
|
||||||
Title string `json:"title" gorm:"not null"`
|
Title string `json:"title" gorm:"not null"`
|
||||||
Statement string `json:"statement" gorm:"not null"`
|
Statement string `json:"statement" gorm:"not null"`
|
||||||
ProviderID uint `json:"-" gorm:"not null;index"`
|
Tags pgtype.TextArray `json:"tags" gorm:"type:text[]"`
|
||||||
Provider User `json:"provider" gorm:"foreignKey:ProviderID"`
|
ProviderID uint `json:"-" gorm:"not null;index"`
|
||||||
IsEnabled bool `json:"is_enabled" gorm:"not null;index"`
|
Provider User `json:"provider" gorm:"foreignKey:ProviderID"`
|
||||||
|
IsEnabled bool `json:"is_enabled" gorm:"not null;index"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProblemVersion struct {
|
type ProblemVersion struct {
|
||||||
|
@ -3,20 +3,25 @@ package problem
|
|||||||
import (
|
import (
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
"git.0x7f.app/WOJ/woj-server/internal/model"
|
||||||
|
"github.com/jackc/pgtype"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateData struct {
|
type CreateData struct {
|
||||||
Title string
|
Title string
|
||||||
Statement string
|
Statement string
|
||||||
|
Tags []string
|
||||||
ProviderID uint
|
ProviderID uint
|
||||||
IsEnabled bool
|
IsEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) Create(data *CreateData) (*model.Problem, e.Status) {
|
func (s *service) Create(data *CreateData) (*model.Problem, e.Status) {
|
||||||
|
tags := pgtype.TextArray{}
|
||||||
|
_ = tags.Set(data.Tags)
|
||||||
problem := &model.Problem{
|
problem := &model.Problem{
|
||||||
Title: data.Title,
|
Title: data.Title,
|
||||||
Statement: data.Statement,
|
Statement: data.Statement,
|
||||||
|
Tags: tags,
|
||||||
ProviderID: data.ProviderID,
|
ProviderID: data.ProviderID,
|
||||||
IsEnabled: data.IsEnabled,
|
IsEnabled: data.IsEnabled,
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package problem
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
|
||||||
"github.com/jackc/pgtype"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CreateVersionData struct {
|
|
||||||
ProblemID uint
|
|
||||||
StorageKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *service) CreateVersion(data *CreateVersionData) (*model.ProblemVersion, e.Status) {
|
|
||||||
problemVersion := &model.ProblemVersion{
|
|
||||||
ProblemID: data.ProblemID,
|
|
||||||
Context: pgtype.JSON{Status: pgtype.Null},
|
|
||||||
StorageKey: data.StorageKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := s.db.Get().Create(problemVersion).Error
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("DatabaseError", zap.Error(err), zap.Any("problemVersion", problemVersion))
|
|
||||||
return nil, e.DatabaseError
|
|
||||||
}
|
|
||||||
|
|
||||||
return problemVersion, e.Success
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package problem
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"gorm.io/gorm/clause"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *service) QueryFuzz(search string, associations bool, shouldEnable bool) ([]*model.Problem, e.Status) {
|
|
||||||
problems := make([]*model.Problem, 0)
|
|
||||||
|
|
||||||
query := s.db.Get()
|
|
||||||
if associations {
|
|
||||||
query = query.Preload(clause.Associations)
|
|
||||||
}
|
|
||||||
if shouldEnable {
|
|
||||||
query = query.Where("is_enabled = true")
|
|
||||||
}
|
|
||||||
query = query.
|
|
||||||
Where(s.db.Get().Where("title LIKE ?", "%"+search+"%").
|
|
||||||
Or("statement LIKE ?", "%"+search+"%"))
|
|
||||||
err := query.Find(&problems).Error
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("DatabaseError", zap.Error(err), zap.Any("search", search))
|
|
||||||
return nil, e.DatabaseError
|
|
||||||
}
|
|
||||||
|
|
||||||
return problems, e.Success
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package problem
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *service) QueryLatestVersion(pid uint) (*model.ProblemVersion, e.Status) {
|
|
||||||
problemVersion := &model.ProblemVersion{
|
|
||||||
ProblemID: pid,
|
|
||||||
IsEnabled: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := s.db.Get().
|
|
||||||
Where(problemVersion).
|
|
||||||
Last(&problemVersion).Error
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, e.ProblemVersionNotFound
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("DatabaseError", zap.Error(err), zap.Any("problemVersion", problemVersion))
|
|
||||||
return nil, e.DatabaseError
|
|
||||||
}
|
|
||||||
|
|
||||||
return problemVersion, e.Success
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package problem
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *service) QueryVersion(pvid uint, shouldEnable bool) (*model.ProblemVersion, e.Status) {
|
|
||||||
problemVersion := new(model.ProblemVersion)
|
|
||||||
|
|
||||||
err := s.db.Get().First(&problemVersion, pvid).Error
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, e.ProblemVersionNotFound
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("DatabaseError", zap.Error(err), zap.Any("pvid", pvid))
|
|
||||||
return nil, e.DatabaseError
|
|
||||||
}
|
|
||||||
|
|
||||||
if shouldEnable && !problemVersion.IsEnabled {
|
|
||||||
return nil, e.ProblemVersionNotAvailable
|
|
||||||
}
|
|
||||||
return problemVersion, e.Success
|
|
||||||
}
|
|
@ -15,7 +15,7 @@ type Service interface {
|
|||||||
Create(data *CreateData) (*model.Problem, e.Status)
|
Create(data *CreateData) (*model.Problem, e.Status)
|
||||||
Update(problem *model.Problem) (*model.Problem, e.Status)
|
Update(problem *model.Problem) (*model.Problem, e.Status)
|
||||||
Query(pid uint, associations bool, shouldEnable bool) (*model.Problem, e.Status)
|
Query(pid uint, associations bool, shouldEnable bool) (*model.Problem, e.Status)
|
||||||
QueryFuzz(search string, associations bool, shouldEnable bool) ([]*model.Problem, e.Status)
|
QueryFuzz(keyword string, tag string, associations bool, shouldEnable bool) ([]*model.Problem, e.Status)
|
||||||
|
|
||||||
CreateVersion(data *CreateVersionData) (*model.ProblemVersion, e.Status)
|
CreateVersion(data *CreateVersionData) (*model.ProblemVersion, e.Status)
|
||||||
UpdateVersion(pvid uint, values interface{}) e.Status
|
UpdateVersion(pvid uint, values interface{}) e.Status
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package problem
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *service) UpdateVersion(pvid uint, values interface{}) e.Status {
|
|
||||||
err := s.db.Get().Model(&model.ProblemVersion{}).Where("id = ?", pvid).Updates(values).Error
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("DatabaseError", zap.Error(err), zap.Any("pvid", pvid), zap.Any("values", values))
|
|
||||||
return e.DatabaseError
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.Success
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user