Spaces:
Running
Running
Commit ·
ce8ca59
1
Parent(s): 864a875
Deploy files from GitHub repository
Browse files
Quzuu_API_Collection.postman_collection.json
CHANGED
|
@@ -4041,7 +4041,7 @@
|
|
| 4041 |
}
|
| 4042 |
],
|
| 4043 |
"url": {
|
| 4044 |
-
"raw": "{{base_url}}/api/v1/admin/problemsets",
|
| 4045 |
"host": [
|
| 4046 |
"{{base_url}}"
|
| 4047 |
],
|
|
@@ -4050,6 +4050,33 @@
|
|
| 4050 |
"v1",
|
| 4051 |
"admin",
|
| 4052 |
"problemsets"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4053 |
]
|
| 4054 |
}
|
| 4055 |
},
|
|
@@ -4177,7 +4204,7 @@
|
|
| 4177 |
}
|
| 4178 |
],
|
| 4179 |
"url": {
|
| 4180 |
-
"raw": "{{base_url}}/api/v1/admin/problemsets/:id/questions",
|
| 4181 |
"host": [
|
| 4182 |
"{{base_url}}"
|
| 4183 |
],
|
|
@@ -4194,6 +4221,33 @@
|
|
| 4194 |
"key": "id",
|
| 4195 |
"value": "{{problemset_id}}"
|
| 4196 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4197 |
]
|
| 4198 |
}
|
| 4199 |
},
|
|
|
|
| 4041 |
}
|
| 4042 |
],
|
| 4043 |
"url": {
|
| 4044 |
+
"raw": "{{base_url}}/api/v1/admin/problemsets?page=1&limit=10&search=&sortBy=title&orderBy=asc",
|
| 4045 |
"host": [
|
| 4046 |
"{{base_url}}"
|
| 4047 |
],
|
|
|
|
| 4050 |
"v1",
|
| 4051 |
"admin",
|
| 4052 |
"problemsets"
|
| 4053 |
+
],
|
| 4054 |
+
"query": [
|
| 4055 |
+
{
|
| 4056 |
+
"key": "page",
|
| 4057 |
+
"value": "1",
|
| 4058 |
+
"description": "Page number"
|
| 4059 |
+
},
|
| 4060 |
+
{
|
| 4061 |
+
"key": "limit",
|
| 4062 |
+
"value": "10",
|
| 4063 |
+
"description": "Items per page (max 100)"
|
| 4064 |
+
},
|
| 4065 |
+
{
|
| 4066 |
+
"key": "search",
|
| 4067 |
+
"value": "",
|
| 4068 |
+
"description": "Search by title / description"
|
| 4069 |
+
},
|
| 4070 |
+
{
|
| 4071 |
+
"key": "sortBy",
|
| 4072 |
+
"value": "title",
|
| 4073 |
+
"description": "Sort field (title, description, created_at)"
|
| 4074 |
+
},
|
| 4075 |
+
{
|
| 4076 |
+
"key": "orderBy",
|
| 4077 |
+
"value": "asc",
|
| 4078 |
+
"description": "Sort direction (asc / desc)"
|
| 4079 |
+
}
|
| 4080 |
]
|
| 4081 |
}
|
| 4082 |
},
|
|
|
|
| 4204 |
}
|
| 4205 |
],
|
| 4206 |
"url": {
|
| 4207 |
+
"raw": "{{base_url}}/api/v1/admin/problemsets/:id/questions?page=1&limit=10&search=&sortBy=id&orderBy=asc",
|
| 4208 |
"host": [
|
| 4209 |
"{{base_url}}"
|
| 4210 |
],
|
|
|
|
| 4221 |
"key": "id",
|
| 4222 |
"value": "{{problemset_id}}"
|
| 4223 |
}
|
| 4224 |
+
],
|
| 4225 |
+
"query": [
|
| 4226 |
+
{
|
| 4227 |
+
"key": "page",
|
| 4228 |
+
"value": "1",
|
| 4229 |
+
"description": "Page number"
|
| 4230 |
+
},
|
| 4231 |
+
{
|
| 4232 |
+
"key": "limit",
|
| 4233 |
+
"value": "10",
|
| 4234 |
+
"description": "Items per page (max 100)"
|
| 4235 |
+
},
|
| 4236 |
+
{
|
| 4237 |
+
"key": "search",
|
| 4238 |
+
"value": "",
|
| 4239 |
+
"description": "Search by question / type"
|
| 4240 |
+
},
|
| 4241 |
+
{
|
| 4242 |
+
"key": "sortBy",
|
| 4243 |
+
"value": "id",
|
| 4244 |
+
"description": "Sort field (id, type, question, corr_mark, incorr_mark, null_mark)"
|
| 4245 |
+
},
|
| 4246 |
+
{
|
| 4247 |
+
"key": "orderBy",
|
| 4248 |
+
"value": "asc",
|
| 4249 |
+
"description": "Sort direction (asc / desc)"
|
| 4250 |
+
}
|
| 4251 |
]
|
| 4252 |
}
|
| 4253 |
},
|
controllers/admin_problemset_controller.go
CHANGED
|
@@ -36,8 +36,57 @@ func NewAdminProblemSetController(problemSetService services.ProblemSetService)
|
|
| 36 |
}
|
| 37 |
|
| 38 |
func (c *adminProblemSetController) ListProblemSets(ctx *gin.Context) {
|
| 39 |
-
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
}
|
| 42 |
|
| 43 |
func (c *adminProblemSetController) CreateProblemSet(ctx *gin.Context) {
|
|
@@ -93,8 +142,59 @@ func (c *adminProblemSetController) ListQuestions(ctx *gin.Context) {
|
|
| 93 |
ResponseJSON[any](ctx, gin.H{"id": ctx.Param("id")}, nil, http_error.INVALID_TOKEN)
|
| 94 |
return
|
| 95 |
}
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
}
|
| 99 |
|
| 100 |
func (c *adminProblemSetController) AddQuestion(ctx *gin.Context) {
|
|
|
|
| 36 |
}
|
| 37 |
|
| 38 |
func (c *adminProblemSetController) ListProblemSets(ctx *gin.Context) {
|
| 39 |
+
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
|
| 40 |
+
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
| 41 |
+
search := ctx.DefaultQuery("search", "")
|
| 42 |
+
sortBy := ctx.DefaultQuery("sortBy", "")
|
| 43 |
+
if sortBy == "" {
|
| 44 |
+
sortBy = ctx.DefaultQuery("sortby", "")
|
| 45 |
+
}
|
| 46 |
+
if sortBy == "" {
|
| 47 |
+
sortBy = ctx.DefaultQuery("sorby", "")
|
| 48 |
+
}
|
| 49 |
+
order := ctx.DefaultQuery("orderBy", "")
|
| 50 |
+
if order == "" {
|
| 51 |
+
order = ctx.DefaultQuery("orderby", "")
|
| 52 |
+
}
|
| 53 |
+
if order == "" {
|
| 54 |
+
order = ctx.DefaultQuery("order", "")
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
if limit < 1 {
|
| 58 |
+
limit = 10
|
| 59 |
+
} else if limit > 100 {
|
| 60 |
+
limit = 100
|
| 61 |
+
}
|
| 62 |
+
if page < 1 {
|
| 63 |
+
page = 1
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
offset := (page - 1) * limit
|
| 67 |
+
p := entity.Pagination{Limit: limit, Offset: offset, Search: search, SortBy: sortBy, Order: order}
|
| 68 |
+
|
| 69 |
+
list, total, err := c.problemSetService.ListProblemSetsWithPagination(ctx.Request.Context(), p)
|
| 70 |
+
if err != nil {
|
| 71 |
+
ResponseJSON[any, any](ctx, nil, nil, err)
|
| 72 |
+
return
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
totalPages := int((total + int64(limit) - 1) / int64(limit))
|
| 76 |
+
if total == 0 {
|
| 77 |
+
totalPages = 1
|
| 78 |
+
}
|
| 79 |
+
if page > totalPages {
|
| 80 |
+
page = totalPages
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
meta := gin.H{
|
| 84 |
+
"totalItems": total,
|
| 85 |
+
"totalPages": totalPages,
|
| 86 |
+
"currentPage": page,
|
| 87 |
+
"limit": limit,
|
| 88 |
+
}
|
| 89 |
+
ResponseJSON(ctx, meta, list, nil)
|
| 90 |
}
|
| 91 |
|
| 92 |
func (c *adminProblemSetController) CreateProblemSet(ctx *gin.Context) {
|
|
|
|
| 142 |
ResponseJSON[any](ctx, gin.H{"id": ctx.Param("id")}, nil, http_error.INVALID_TOKEN)
|
| 143 |
return
|
| 144 |
}
|
| 145 |
+
|
| 146 |
+
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
|
| 147 |
+
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
| 148 |
+
search := ctx.DefaultQuery("search", "")
|
| 149 |
+
sortBy := ctx.DefaultQuery("sortBy", "")
|
| 150 |
+
if sortBy == "" {
|
| 151 |
+
sortBy = ctx.DefaultQuery("sortby", "")
|
| 152 |
+
}
|
| 153 |
+
if sortBy == "" {
|
| 154 |
+
sortBy = ctx.DefaultQuery("sorby", "")
|
| 155 |
+
}
|
| 156 |
+
order := ctx.DefaultQuery("orderBy", "")
|
| 157 |
+
if order == "" {
|
| 158 |
+
order = ctx.DefaultQuery("orderby", "")
|
| 159 |
+
}
|
| 160 |
+
if order == "" {
|
| 161 |
+
order = ctx.DefaultQuery("order", "")
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
if limit < 1 {
|
| 165 |
+
limit = 10
|
| 166 |
+
} else if limit > 100 {
|
| 167 |
+
limit = 100
|
| 168 |
+
}
|
| 169 |
+
if page < 1 {
|
| 170 |
+
page = 1
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
offset := (page - 1) * limit
|
| 174 |
+
p := entity.Pagination{Limit: limit, Offset: offset, Search: search, SortBy: sortBy, Order: order}
|
| 175 |
+
|
| 176 |
+
list, total, listErr := c.problemSetService.ListQuestionsWithPagination(ctx.Request.Context(), problemSetId, p)
|
| 177 |
+
if listErr != nil {
|
| 178 |
+
ResponseJSON[any, any](ctx, nil, nil, listErr)
|
| 179 |
+
return
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
totalPages := int((total + int64(limit) - 1) / int64(limit))
|
| 183 |
+
if total == 0 {
|
| 184 |
+
totalPages = 1
|
| 185 |
+
}
|
| 186 |
+
if page > totalPages {
|
| 187 |
+
page = totalPages
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
meta := gin.H{
|
| 191 |
+
"problemset_id": problemSetId,
|
| 192 |
+
"totalItems": total,
|
| 193 |
+
"totalPages": totalPages,
|
| 194 |
+
"currentPage": page,
|
| 195 |
+
"limit": limit,
|
| 196 |
+
}
|
| 197 |
+
ResponseJSON(ctx, meta, list, nil)
|
| 198 |
}
|
| 199 |
|
| 200 |
func (c *adminProblemSetController) AddQuestion(ctx *gin.Context) {
|
repositories/problem_set_repository.go
CHANGED
|
@@ -1,57 +1,102 @@
|
|
| 1 |
-
package repositories
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"context"
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
"
|
| 8 |
-
"
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package repositories
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
"strings"
|
| 6 |
+
|
| 7 |
+
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 8 |
+
"github.com/google/uuid"
|
| 9 |
+
"gorm.io/gorm"
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
type ProblemSetRepository interface {
|
| 13 |
+
Create(ctx context.Context, ps entity.ProblemSet) error
|
| 14 |
+
Get(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error)
|
| 15 |
+
Update(ctx context.Context, ps entity.ProblemSet) error
|
| 16 |
+
Delete(ctx context.Context, id uuid.UUID) error
|
| 17 |
+
List(ctx context.Context) ([]entity.ProblemSet, error)
|
| 18 |
+
ListWithPagination(ctx context.Context, p entity.Pagination) ([]entity.ProblemSet, int64, error)
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
type problemSetRepository struct {
|
| 22 |
+
db *gorm.DB
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
func NewProblemSetRepository(db *gorm.DB) ProblemSetRepository {
|
| 26 |
+
return &problemSetRepository{db: db}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
func (r *problemSetRepository) Create(ctx context.Context, ps entity.ProblemSet) error {
|
| 30 |
+
return r.db.WithContext(ctx).Create(&ps).Error
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
func (r *problemSetRepository) Get(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error) {
|
| 34 |
+
var ps entity.ProblemSet
|
| 35 |
+
err := r.db.WithContext(ctx).
|
| 36 |
+
First(&ps, "id = ?", id).Error
|
| 37 |
+
return ps, err
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
func (r *problemSetRepository) List(ctx context.Context) ([]entity.ProblemSet, error) {
|
| 41 |
+
var list []entity.ProblemSet
|
| 42 |
+
err := r.db.WithContext(ctx).
|
| 43 |
+
Order("title").
|
| 44 |
+
Find(&list).Error
|
| 45 |
+
return list, err
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
func (r *problemSetRepository) ListWithPagination(ctx context.Context, p entity.Pagination) ([]entity.ProblemSet, int64, error) {
|
| 49 |
+
var list []entity.ProblemSet
|
| 50 |
+
|
| 51 |
+
countQ := r.db.WithContext(ctx).Model(&entity.ProblemSet{})
|
| 52 |
+
if s := strings.TrimSpace(p.Search); s != "" {
|
| 53 |
+
like := "%" + strings.ToLower(s) + "%"
|
| 54 |
+
countQ = countQ.Where("LOWER(title) LIKE ? OR LOWER(description) LIKE ?", like, like)
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
var total int64
|
| 58 |
+
if err := countQ.Count(&total).Error; err != nil {
|
| 59 |
+
return nil, 0, err
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
q := r.db.WithContext(ctx).Model(&entity.ProblemSet{})
|
| 63 |
+
if s := strings.TrimSpace(p.Search); s != "" {
|
| 64 |
+
like := "%" + strings.ToLower(s) + "%"
|
| 65 |
+
q = q.Where("LOWER(title) LIKE ? OR LOWER(description) LIKE ?", like, like)
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
col := strings.ToLower(strings.TrimSpace(p.SortBy))
|
| 69 |
+
ord := strings.ToLower(strings.TrimSpace(p.Order))
|
| 70 |
+
if ord != "desc" {
|
| 71 |
+
ord = "asc"
|
| 72 |
+
}
|
| 73 |
+
switch col {
|
| 74 |
+
case "title", "description", "created_at":
|
| 75 |
+
q = q.Order(col + " " + ord)
|
| 76 |
+
default:
|
| 77 |
+
q = q.Order("title " + ord)
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
if p.Limit > 0 {
|
| 81 |
+
q = q.Limit(p.Limit)
|
| 82 |
+
}
|
| 83 |
+
if p.Offset > 0 {
|
| 84 |
+
q = q.Offset(p.Offset)
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
err := q.Find(&list).Error
|
| 88 |
+
return list, total, err
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
func (r *problemSetRepository) Update(ctx context.Context, ps entity.ProblemSet) error {
|
| 92 |
+
return r.db.WithContext(ctx).
|
| 93 |
+
Model(&entity.ProblemSet{}).
|
| 94 |
+
Where("id = ?", ps.Id).
|
| 95 |
+
Updates(ps).Error
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
func (r *problemSetRepository) Delete(ctx context.Context, id uuid.UUID) error {
|
| 99 |
+
return r.db.WithContext(ctx).
|
| 100 |
+
Where("id = ?", id).
|
| 101 |
+
Delete(&entity.ProblemSet{}).Error
|
| 102 |
+
}
|
repositories/question_repository.go
CHANGED
|
@@ -2,7 +2,7 @@ package repositories
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
-
|
| 6 |
|
| 7 |
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 8 |
"github.com/google/uuid"
|
|
@@ -15,6 +15,7 @@ type QuestionsRepository interface {
|
|
| 15 |
Update(ctx context.Context, q entity.Questions) error
|
| 16 |
Delete(ctx context.Context, id uuid.UUID) error
|
| 17 |
ListByProblemSet(ctx context.Context, problemSetId uuid.UUID) ([]entity.Questions, error)
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
type questionsRepository struct{ db *gorm.DB }
|
|
@@ -55,3 +56,51 @@ func (r *questionsRepository) ListByProblemSet(ctx context.Context, problemSetId
|
|
| 55 |
return q, err
|
| 56 |
}
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"context"
|
| 5 |
+
"strings"
|
| 6 |
|
| 7 |
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 8 |
"github.com/google/uuid"
|
|
|
|
| 15 |
Update(ctx context.Context, q entity.Questions) error
|
| 16 |
Delete(ctx context.Context, id uuid.UUID) error
|
| 17 |
ListByProblemSet(ctx context.Context, problemSetId uuid.UUID) ([]entity.Questions, error)
|
| 18 |
+
ListByProblemSetWithPagination(ctx context.Context, problemSetId uuid.UUID, p entity.Pagination) ([]entity.Questions, int64, error)
|
| 19 |
}
|
| 20 |
|
| 21 |
type questionsRepository struct{ db *gorm.DB }
|
|
|
|
| 56 |
return q, err
|
| 57 |
}
|
| 58 |
|
| 59 |
+
func (r *questionsRepository) ListByProblemSetWithPagination(ctx context.Context, problemSetId uuid.UUID, p entity.Pagination) ([]entity.Questions, int64, error) {
|
| 60 |
+
var list []entity.Questions
|
| 61 |
+
|
| 62 |
+
countQ := r.db.WithContext(ctx).
|
| 63 |
+
Model(&entity.Questions{}).
|
| 64 |
+
Where("problem_set_id = ?", problemSetId)
|
| 65 |
+
|
| 66 |
+
if s := strings.TrimSpace(p.Search); s != "" {
|
| 67 |
+
like := "%" + strings.ToLower(s) + "%"
|
| 68 |
+
countQ = countQ.Where("LOWER(type) LIKE ? OR LOWER(question) LIKE ?", like, like)
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
var total int64
|
| 72 |
+
if err := countQ.Count(&total).Error; err != nil {
|
| 73 |
+
return nil, 0, err
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
q := r.db.WithContext(ctx).
|
| 77 |
+
Model(&entity.Questions{}).
|
| 78 |
+
Where("problem_set_id = ?", problemSetId)
|
| 79 |
+
|
| 80 |
+
if s := strings.TrimSpace(p.Search); s != "" {
|
| 81 |
+
like := "%" + strings.ToLower(s) + "%"
|
| 82 |
+
q = q.Where("LOWER(type) LIKE ? OR LOWER(question) LIKE ?", like, like)
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
col := strings.ToLower(strings.TrimSpace(p.SortBy))
|
| 86 |
+
ord := strings.ToLower(strings.TrimSpace(p.Order))
|
| 87 |
+
if ord != "desc" {
|
| 88 |
+
ord = "asc"
|
| 89 |
+
}
|
| 90 |
+
switch col {
|
| 91 |
+
case "id", "type", "question", "corr_mark", "incorr_mark", "null_mark":
|
| 92 |
+
q = q.Order(col + " " + ord)
|
| 93 |
+
default:
|
| 94 |
+
q = q.Order("id " + ord)
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
if p.Limit > 0 {
|
| 98 |
+
q = q.Limit(p.Limit)
|
| 99 |
+
}
|
| 100 |
+
if p.Offset > 0 {
|
| 101 |
+
q = q.Offset(p.Offset)
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
err := q.Find(&list).Error
|
| 105 |
+
return list, total, err
|
| 106 |
+
}
|
services/problem_set_service.go
CHANGED
|
@@ -17,6 +17,7 @@ type ProblemSetService interface {
|
|
| 17 |
CreateProblemSet(ctx context.Context, ps entity.ProblemSet) error
|
| 18 |
GetProblemSet(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error)
|
| 19 |
ListProblemSets(ctx context.Context) ([]entity.ProblemSet, error)
|
|
|
|
| 20 |
UpdateProblemSet(ctx context.Context, ps entity.ProblemSet) error
|
| 21 |
DeleteProblemSet(ctx context.Context, id uuid.UUID) error
|
| 22 |
|
|
@@ -24,6 +25,7 @@ type ProblemSetService interface {
|
|
| 24 |
UpdateQuestion(ctx context.Context, q entity.Questions) error
|
| 25 |
DeleteQuestion(ctx context.Context, qID uuid.UUID) error
|
| 26 |
ListQuestions(ctx context.Context, psID uuid.UUID) ([]entity.Questions, error)
|
|
|
|
| 27 |
|
| 28 |
ListProblemSetsByExam(ctx context.Context, examId uuid.UUID, p entity.Pagination) ([]entity.ProblemSetExamAssign, int64, error)
|
| 29 |
ListCandidateProblemSetsByExam(ctx context.Context, examId uuid.UUID, p entity.Pagination) ([]entity.ProblemSet, int64, error)
|
|
@@ -70,6 +72,10 @@ func (s *problemSetService) ListProblemSets(ctx context.Context) ([]entity.Probl
|
|
| 70 |
return s.problemSetRepository.List(ctx)
|
| 71 |
}
|
| 72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
func (s *problemSetService) UpdateProblemSet(ctx context.Context, ps entity.ProblemSet) error {
|
| 74 |
_, err := s.problemSetRepository.Get(ctx, ps.Id)
|
| 75 |
if err != nil {
|
|
@@ -120,6 +126,14 @@ func (s *problemSetService) ListQuestions(ctx context.Context, psID uuid.UUID) (
|
|
| 120 |
return s.questionsRepository.ListByProblemSet(ctx, psID)
|
| 121 |
}
|
| 122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
// ---------------- Exam ↔ Problem Set (Mapping Table) ----------------
|
| 124 |
|
| 125 |
func (s *problemSetService) AssignProblemSetToExam(ctx context.Context, examId uuid.UUID, problemSetId uuid.UUID) error {
|
|
@@ -181,4 +195,3 @@ func (s *problemSetService) ListQuestionsByExam(ctx context.Context, examId uuid
|
|
| 181 |
}
|
| 182 |
return s.questionsRepository.ListByProblemSet(ctx, assign.ProblemSetId)
|
| 183 |
}
|
| 184 |
-
|
|
|
|
| 17 |
CreateProblemSet(ctx context.Context, ps entity.ProblemSet) error
|
| 18 |
GetProblemSet(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error)
|
| 19 |
ListProblemSets(ctx context.Context) ([]entity.ProblemSet, error)
|
| 20 |
+
ListProblemSetsWithPagination(ctx context.Context, p entity.Pagination) ([]entity.ProblemSet, int64, error)
|
| 21 |
UpdateProblemSet(ctx context.Context, ps entity.ProblemSet) error
|
| 22 |
DeleteProblemSet(ctx context.Context, id uuid.UUID) error
|
| 23 |
|
|
|
|
| 25 |
UpdateQuestion(ctx context.Context, q entity.Questions) error
|
| 26 |
DeleteQuestion(ctx context.Context, qID uuid.UUID) error
|
| 27 |
ListQuestions(ctx context.Context, psID uuid.UUID) ([]entity.Questions, error)
|
| 28 |
+
ListQuestionsWithPagination(ctx context.Context, psID uuid.UUID, p entity.Pagination) ([]entity.Questions, int64, error)
|
| 29 |
|
| 30 |
ListProblemSetsByExam(ctx context.Context, examId uuid.UUID, p entity.Pagination) ([]entity.ProblemSetExamAssign, int64, error)
|
| 31 |
ListCandidateProblemSetsByExam(ctx context.Context, examId uuid.UUID, p entity.Pagination) ([]entity.ProblemSet, int64, error)
|
|
|
|
| 72 |
return s.problemSetRepository.List(ctx)
|
| 73 |
}
|
| 74 |
|
| 75 |
+
func (s *problemSetService) ListProblemSetsWithPagination(ctx context.Context, p entity.Pagination) ([]entity.ProblemSet, int64, error) {
|
| 76 |
+
return s.problemSetRepository.ListWithPagination(ctx, p)
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
func (s *problemSetService) UpdateProblemSet(ctx context.Context, ps entity.ProblemSet) error {
|
| 80 |
_, err := s.problemSetRepository.Get(ctx, ps.Id)
|
| 81 |
if err != nil {
|
|
|
|
| 126 |
return s.questionsRepository.ListByProblemSet(ctx, psID)
|
| 127 |
}
|
| 128 |
|
| 129 |
+
func (s *problemSetService) ListQuestionsWithPagination(ctx context.Context, psID uuid.UUID, p entity.Pagination) ([]entity.Questions, int64, error) {
|
| 130 |
+
_, err := s.problemSetRepository.Get(ctx, psID)
|
| 131 |
+
if err != nil {
|
| 132 |
+
return nil, 0, http_error.PROBLEM_SET_NOT_FOUND
|
| 133 |
+
}
|
| 134 |
+
return s.questionsRepository.ListByProblemSetWithPagination(ctx, psID, p)
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
// ---------------- Exam ↔ Problem Set (Mapping Table) ----------------
|
| 138 |
|
| 139 |
func (s *problemSetService) AssignProblemSetToExam(ctx context.Context, examId uuid.UUID, problemSetId uuid.UUID) error {
|
|
|
|
| 195 |
}
|
| 196 |
return s.questionsRepository.ListByProblemSet(ctx, assign.ProblemSetId)
|
| 197 |
}
|
|
|