Spaces:
Sleeping
Sleeping
Commit ·
aa6ea88
1
Parent(s): c32f786
Deploy files from GitHub repository
Browse files- controllers/academy_controller.go +43 -3
- models/dto/academy_dto.go +38 -31
- models/entity/entity.go +3 -3
- repositories/academy_repository.go +1 -1
- router/academy_router.go +20 -19
- services/academy_service.go +65 -4
controllers/academy_controller.go
CHANGED
|
@@ -17,7 +17,7 @@ type AcademyController interface {
|
|
| 17 |
CreateAcademy(ctx *gin.Context)
|
| 18 |
GetAcademy(ctx *gin.Context)
|
| 19 |
GetAcademyDetail(ctx *gin.Context)
|
| 20 |
-
|
| 21 |
UpdateAcademy(ctx *gin.Context)
|
| 22 |
DeleteAcademy(ctx *gin.Context)
|
| 23 |
JoinAcademyByCode(ctx *gin.Context)
|
|
@@ -73,26 +73,66 @@ func (c *academyController) GetAcademyDetail(ctx *gin.Context) {
|
|
| 73 |
ResponseJSON(ctx, gin.H{"id": id}, res, err)
|
| 74 |
}
|
| 75 |
|
| 76 |
-
func (c *academyController)
|
| 77 |
accountIdStr := ctx.GetString("account_id")
|
| 78 |
accountId, err := uuid.Parse(accountIdStr)
|
| 79 |
if err != nil {
|
| 80 |
ResponseJSON[any, any](ctx, nil, nil, http_error.UNAUTHORIZED)
|
| 81 |
return
|
| 82 |
}
|
|
|
|
| 83 |
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
|
| 84 |
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
if page < 1 {
|
| 86 |
page = 1
|
|
|
|
| 87 |
}
|
|
|
|
| 88 |
offset := (page - 1) * limit
|
| 89 |
p := repositories.Pagination{Limit: limit, Offset: offset}
|
| 90 |
-
list, total, err := c.academyService.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
meta := gin.H{
|
| 92 |
"total_records": total,
|
| 93 |
"page_size": limit,
|
| 94 |
"current_page": page,
|
|
|
|
| 95 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
ResponseJSON(ctx, meta, list, err)
|
| 97 |
}
|
| 98 |
|
|
|
|
| 17 |
CreateAcademy(ctx *gin.Context)
|
| 18 |
GetAcademy(ctx *gin.Context)
|
| 19 |
GetAcademyDetail(ctx *gin.Context)
|
| 20 |
+
ListAcademy(ctx *gin.Context)
|
| 21 |
UpdateAcademy(ctx *gin.Context)
|
| 22 |
DeleteAcademy(ctx *gin.Context)
|
| 23 |
JoinAcademyByCode(ctx *gin.Context)
|
|
|
|
| 73 |
ResponseJSON(ctx, gin.H{"id": id}, res, err)
|
| 74 |
}
|
| 75 |
|
| 76 |
+
func (c *academyController) ListAcademy(ctx *gin.Context) {
|
| 77 |
accountIdStr := ctx.GetString("account_id")
|
| 78 |
accountId, err := uuid.Parse(accountIdStr)
|
| 79 |
if err != nil {
|
| 80 |
ResponseJSON[any, any](ctx, nil, nil, http_error.UNAUTHORIZED)
|
| 81 |
return
|
| 82 |
}
|
| 83 |
+
|
| 84 |
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
|
| 85 |
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
|
| 86 |
+
isModified := false
|
| 87 |
+
|
| 88 |
+
if limit < 1 {
|
| 89 |
+
limit = 10
|
| 90 |
+
isModified = true
|
| 91 |
+
} else if limit > 50 {
|
| 92 |
+
limit = 50
|
| 93 |
+
isModified = true
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
if page < 1 {
|
| 97 |
page = 1
|
| 98 |
+
isModified = true
|
| 99 |
}
|
| 100 |
+
|
| 101 |
offset := (page - 1) * limit
|
| 102 |
p := repositories.Pagination{Limit: limit, Offset: offset}
|
| 103 |
+
list, total, err := c.academyService.ListAcademy(ctx.Request.Context(), accountId, p)
|
| 104 |
+
|
| 105 |
+
if err != nil {
|
| 106 |
+
ResponseJSON[any, any](ctx, nil, nil, err)
|
| 107 |
+
return
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
var totalPages int
|
| 111 |
+
if total == 0 {
|
| 112 |
+
totalPages = 1
|
| 113 |
+
} else {
|
| 114 |
+
totalPages = int((total + int64(limit) - 1) / int64(limit))
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
if page > totalPages {
|
| 118 |
+
page = totalPages
|
| 119 |
+
offset = (page - 1) * limit
|
| 120 |
+
p.Offset = offset
|
| 121 |
+
list, total, err = c.academyService.ListAcademy(ctx.Request.Context(), accountId, p)
|
| 122 |
+
isModified = true
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
meta := gin.H{
|
| 126 |
"total_records": total,
|
| 127 |
"page_size": limit,
|
| 128 |
"current_page": page,
|
| 129 |
+
"is_modified": isModified,
|
| 130 |
}
|
| 131 |
+
|
| 132 |
+
if isModified {
|
| 133 |
+
ctx.Status(http.StatusAccepted)
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
ResponseJSON(ctx, meta, list, err)
|
| 137 |
}
|
| 138 |
|
models/dto/academy_dto.go
CHANGED
|
@@ -44,6 +44,17 @@ type AcademyProgressResponse struct {
|
|
| 44 |
CompletedAt *string `json:"completed_at"`
|
| 45 |
}
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
type AcademyContentResponse struct {
|
| 48 |
Id uuid.UUID `json:"id"`
|
| 49 |
Order uint `json:"order"`
|
|
@@ -64,6 +75,26 @@ type AcademyMaterialResponse struct {
|
|
| 64 |
Contents []AcademyContentResponse `json:"contents"`
|
| 65 |
}
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
type AcademyDetailResponse struct {
|
| 68 |
Id uuid.UUID `json:"id"`
|
| 69 |
Title string `json:"title"`
|
|
@@ -77,37 +108,6 @@ type AcademyDetailResponse struct {
|
|
| 77 |
RegisterStatus int `json:"register_status" binding:"required"`
|
| 78 |
}
|
| 79 |
|
| 80 |
-
type MaterialPreview struct {
|
| 81 |
-
Id uuid.UUID `json:"id"`
|
| 82 |
-
Title string `json:"title"`
|
| 83 |
-
Order uint `json:"order"`
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
type AcademyPublicPreviewResponse struct {
|
| 87 |
-
Id uuid.UUID `json:"id"`
|
| 88 |
-
Title string `json:"title"`
|
| 89 |
-
RegisterStatus int `json:"register_status" binding:"required"`
|
| 90 |
-
Materials []MaterialPreview `json:"materials"`
|
| 91 |
-
}
|
| 92 |
-
|
| 93 |
-
type MaterialProgressResponse struct {
|
| 94 |
-
Id uuid.UUID `json:"id"`
|
| 95 |
-
AccountId uuid.UUID `json:"account_id"`
|
| 96 |
-
AcademyId uuid.UUID `json:"academy_id"`
|
| 97 |
-
MaterialId uuid.UUID `json:"material_id"`
|
| 98 |
-
Progress float64 `json:"progress"`
|
| 99 |
-
TotalCompletedContents uint `json:"total_completed_contents"`
|
| 100 |
-
Status string `json:"status"`
|
| 101 |
-
CompletedAt *string `json:"completed_at"`
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
type ContentDetailResponse struct {
|
| 105 |
-
Id uuid.UUID `json:"id"`
|
| 106 |
-
Order uint `json:"order"`
|
| 107 |
-
Title string `json:"title"`
|
| 108 |
-
Status string `json:"status"`
|
| 109 |
-
}
|
| 110 |
-
|
| 111 |
type MaterialDetailResponse struct {
|
| 112 |
Id uuid.UUID `json:"id"`
|
| 113 |
AcademyId uuid.UUID `json:"academy_id"`
|
|
@@ -121,6 +121,13 @@ type MaterialDetailResponse struct {
|
|
| 121 |
Meta map[string]string `json:"meta"`
|
| 122 |
}
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
type AssignRequest struct {
|
| 125 |
AcademyId string `json:"academy_id"`
|
| 126 |
AccountId string `json:"account_id"`
|
|
|
|
| 44 |
CompletedAt *string `json:"completed_at"`
|
| 45 |
}
|
| 46 |
|
| 47 |
+
type MaterialProgressResponse struct {
|
| 48 |
+
Id uuid.UUID `json:"id"`
|
| 49 |
+
AccountId uuid.UUID `json:"account_id"`
|
| 50 |
+
AcademyId uuid.UUID `json:"academy_id"`
|
| 51 |
+
MaterialId uuid.UUID `json:"material_id"`
|
| 52 |
+
Progress float64 `json:"progress"`
|
| 53 |
+
TotalCompletedContents uint `json:"total_completed_contents"`
|
| 54 |
+
Status string `json:"status"`
|
| 55 |
+
CompletedAt *string `json:"completed_at"`
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
type AcademyContentResponse struct {
|
| 59 |
Id uuid.UUID `json:"id"`
|
| 60 |
Order uint `json:"order"`
|
|
|
|
| 75 |
Contents []AcademyContentResponse `json:"contents"`
|
| 76 |
}
|
| 77 |
|
| 78 |
+
// PREVIEW DTOs
|
| 79 |
+
|
| 80 |
+
type AcademyPublicPreviewResponse struct {
|
| 81 |
+
Id uuid.UUID `json:"id"`
|
| 82 |
+
Title string `json:"title"`
|
| 83 |
+
Description string `json:"description"`
|
| 84 |
+
ImageUrl string `json:"image_url"`
|
| 85 |
+
Code string `json:"code"`
|
| 86 |
+
RegisterStatus int `json:"register_status" binding:"required"`
|
| 87 |
+
Materials []MaterialPreview `json:"materials"`
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
type MaterialPreview struct {
|
| 91 |
+
Id uuid.UUID `json:"id"`
|
| 92 |
+
Title string `json:"title"`
|
| 93 |
+
Order uint `json:"order"`
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// Detail Response
|
| 97 |
+
|
| 98 |
type AcademyDetailResponse struct {
|
| 99 |
Id uuid.UUID `json:"id"`
|
| 100 |
Title string `json:"title"`
|
|
|
|
| 108 |
RegisterStatus int `json:"register_status" binding:"required"`
|
| 109 |
}
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
type MaterialDetailResponse struct {
|
| 112 |
Id uuid.UUID `json:"id"`
|
| 113 |
AcademyId uuid.UUID `json:"academy_id"`
|
|
|
|
| 121 |
Meta map[string]string `json:"meta"`
|
| 122 |
}
|
| 123 |
|
| 124 |
+
type ContentDetailResponse struct {
|
| 125 |
+
Id uuid.UUID `json:"id"`
|
| 126 |
+
Order uint `json:"order"`
|
| 127 |
+
Title string `json:"title"`
|
| 128 |
+
Status string `json:"status"`
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
type AssignRequest struct {
|
| 132 |
AcademyId string `json:"academy_id"`
|
| 133 |
AccountId string `json:"account_id"`
|
models/entity/entity.go
CHANGED
|
@@ -300,7 +300,7 @@ func (AcademyContent) TableName() string { return "academy_contents" }
|
|
| 300 |
// Progress
|
| 301 |
|
| 302 |
type AcademyProgress struct {
|
| 303 |
-
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
|
| 304 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_academy" json:"account_id,omitempty"`
|
| 305 |
AcademyId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_academy" json:"academy_id,omitempty"`
|
| 306 |
Status string `gorm:"type:varchar(50);default:'not attempted'" json:"status,omitempty"`
|
|
@@ -312,7 +312,7 @@ type AcademyProgress struct {
|
|
| 312 |
func (AcademyProgress) TableName() string { return "academy_progress" }
|
| 313 |
|
| 314 |
type AcademyMaterialProgress struct {
|
| 315 |
-
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
|
| 316 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_material" json:"account_id,omitempty"`
|
| 317 |
AcademyId uuid.UUID `gorm:"type:uuid;index" json:"academy_id,omitempty"`
|
| 318 |
MaterialId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_material" json:"material_id,omitempty"`
|
|
@@ -325,7 +325,7 @@ type AcademyMaterialProgress struct {
|
|
| 325 |
func (AcademyMaterialProgress) TableName() string { return "academy_material_progress" }
|
| 326 |
|
| 327 |
type AcademyContentProgress struct {
|
| 328 |
-
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
|
| 329 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_content" json:"account_id,omitempty"`
|
| 330 |
AcademyId uuid.UUID `gorm:"type:uuid;index" json:"academy_id,omitempty"`
|
| 331 |
MaterialId uuid.UUID `gorm:"type:uuid;index" json:"material_id,omitempty"`
|
|
|
|
| 300 |
// Progress
|
| 301 |
|
| 302 |
type AcademyProgress struct {
|
| 303 |
+
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id,omitempty"`
|
| 304 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_academy" json:"account_id,omitempty"`
|
| 305 |
AcademyId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_academy" json:"academy_id,omitempty"`
|
| 306 |
Status string `gorm:"type:varchar(50);default:'not attempted'" json:"status,omitempty"`
|
|
|
|
| 312 |
func (AcademyProgress) TableName() string { return "academy_progress" }
|
| 313 |
|
| 314 |
type AcademyMaterialProgress struct {
|
| 315 |
+
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id,omitempty"`
|
| 316 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_material" json:"account_id,omitempty"`
|
| 317 |
AcademyId uuid.UUID `gorm:"type:uuid;index" json:"academy_id,omitempty"`
|
| 318 |
MaterialId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_material" json:"material_id,omitempty"`
|
|
|
|
| 325 |
func (AcademyMaterialProgress) TableName() string { return "academy_material_progress" }
|
| 326 |
|
| 327 |
type AcademyContentProgress struct {
|
| 328 |
+
Id uuid.UUID `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id,omitempty"`
|
| 329 |
AccountId uuid.UUID `gorm:"type:uuid;uniqueIndex:idx_account_content" json:"account_id,omitempty"`
|
| 330 |
AcademyId uuid.UUID `gorm:"type:uuid;index" json:"academy_id,omitempty"`
|
| 331 |
MaterialId uuid.UUID `gorm:"type:uuid;index" json:"material_id,omitempty"`
|
repositories/academy_repository.go
CHANGED
|
@@ -384,7 +384,7 @@ func (r *academyRepository) GetContentProgress(ctx context.Context, accountId uu
|
|
| 384 |
AcademyId: academyId,
|
| 385 |
MaterialId: materialId,
|
| 386 |
ContentId: contentId,
|
| 387 |
-
Status: entity.
|
| 388 |
}, nil
|
| 389 |
}
|
| 390 |
return existing, err
|
|
|
|
| 384 |
AcademyId: academyId,
|
| 385 |
MaterialId: materialId,
|
| 386 |
ContentId: contentId,
|
| 387 |
+
Status: entity.StatusInProgress,
|
| 388 |
}, nil
|
| 389 |
}
|
| 390 |
return existing, err
|
router/academy_router.go
CHANGED
|
@@ -12,25 +12,26 @@ func AcademyRouter(router *gin.Engine, middleware provider.MiddlewareProvider, c
|
|
| 12 |
routerGroup := router.Group("/api/v1/academy")
|
| 13 |
|
| 14 |
routerGroup.Use(gzip.Gzip(gzip.DefaultCompression))
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
|
|
|
| 34 |
routerGroup.POST("/join", authenticationMiddleware.VerifyAccount, academyController.JoinAcademyByCode)
|
| 35 |
routerGroup.GET("/:academy_slug", authenticationMiddleware.VerifyAccount, academyController.GetAcademy)
|
| 36 |
routerGroup.GET("/:academy_slug/:material_slug", authenticationMiddleware.VerifyAccount, academyController.GetMaterial)
|
|
|
|
| 12 |
routerGroup := router.Group("/api/v1/academy")
|
| 13 |
|
| 14 |
routerGroup.Use(gzip.Gzip(gzip.DefaultCompression))
|
| 15 |
+
{
|
| 16 |
+
adminGroup := routerGroup.Group("/admin", authenticationMiddleware.VerifyAccount)
|
| 17 |
+
|
| 18 |
+
adminGroup.POST("/", academyController.CreateAcademy)
|
| 19 |
+
adminGroup.GET("/id/:id/detail", academyController.GetAcademyDetail)
|
| 20 |
+
adminGroup.PUT("/id/:id", academyController.UpdateAcademy)
|
| 21 |
+
adminGroup.DELETE("/id/:id", academyController.DeleteAcademy)
|
| 22 |
+
|
| 23 |
+
adminGroup.POST("/materials", academyController.CreateMaterial)
|
| 24 |
+
adminGroup.DELETE("/materials/:id", academyController.DeleteMaterial)
|
| 25 |
+
|
| 26 |
+
adminGroup.POST("/contents", academyController.CreateContent)
|
| 27 |
+
adminGroup.DELETE("/contents/:id", academyController.DeleteContent)
|
| 28 |
+
|
| 29 |
+
adminGroup.POST("/assign", academyController.AssignAccountToAcademy)
|
| 30 |
+
adminGroup.DELETE("/assign/:id", academyController.UnassignAccountFromAcademy)
|
| 31 |
+
adminGroup.GET("/assign/:academy_id", academyController.ListAssignmentsByAcademy)
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
routerGroup.GET("/", authenticationMiddleware.VerifyAccount, academyController.ListAcademy)
|
| 35 |
routerGroup.POST("/join", authenticationMiddleware.VerifyAccount, academyController.JoinAcademyByCode)
|
| 36 |
routerGroup.GET("/:academy_slug", authenticationMiddleware.VerifyAccount, academyController.GetAcademy)
|
| 37 |
routerGroup.GET("/:academy_slug/:material_slug", authenticationMiddleware.VerifyAccount, academyController.GetMaterial)
|
services/academy_service.go
CHANGED
|
@@ -22,7 +22,7 @@ type AcademyService interface {
|
|
| 22 |
CreateAcademy(ctx context.Context, req dto.CreateAcademyRequest) (entity.Academy, error)
|
| 23 |
UpdateAcademy(ctx context.Context, id uuid.UUID, req dto.UpdateAcademyRequest) (entity.Academy, error)
|
| 24 |
DeleteAcademy(ctx context.Context, id uuid.UUID) error
|
| 25 |
-
|
| 26 |
|
| 27 |
CreateMaterial(ctx context.Context, req dto.CreateMaterialRequest) (entity.AcademyMaterial, error)
|
| 28 |
GetMaterial(ctx context.Context, accountId uuid.UUID, academySlug string, materialSlug string) (entity.AcademyMaterial, error)
|
|
@@ -145,7 +145,7 @@ func (s *academyService) DeleteAcademy(ctx context.Context, id uuid.UUID) error
|
|
| 145 |
return s.academyRepo.DeleteAcademy(ctx, id)
|
| 146 |
}
|
| 147 |
|
| 148 |
-
func (s *academyService)
|
| 149 |
list, total, err := s.academyRepo.ListVisibleAcademy(ctx, accountId, &p)
|
| 150 |
return list, total, err
|
| 151 |
}
|
|
@@ -321,6 +321,55 @@ func (s *academyService) GetContent(ctx context.Context, accountId uuid.UUID, ac
|
|
| 321 |
if err != nil {
|
| 322 |
return entity.AcademyContent{}, err
|
| 323 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 324 |
return s.academyRepo.GetContentWithProgress(ctx, accountId, material.AcademyId, material.Id, order)
|
| 325 |
}
|
| 326 |
|
|
@@ -515,9 +564,21 @@ func (s *academyService) GetAcademyResponse(ctx context.Context, accountId uuid.
|
|
| 515 |
}
|
| 516 |
previews := make([]dto.MaterialPreview, len(mats))
|
| 517 |
for i, m := range mats {
|
| 518 |
-
previews[i] = dto.MaterialPreview{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
}
|
| 520 |
-
res := dto.AcademyPublicPreviewResponse{Id: academy.Id, Title: academy.Title, RegisterStatus: 0, Materials: previews}
|
| 521 |
return res, nil
|
| 522 |
}
|
| 523 |
return nil, http_error.UNAUTHORIZED
|
|
|
|
| 22 |
CreateAcademy(ctx context.Context, req dto.CreateAcademyRequest) (entity.Academy, error)
|
| 23 |
UpdateAcademy(ctx context.Context, id uuid.UUID, req dto.UpdateAcademyRequest) (entity.Academy, error)
|
| 24 |
DeleteAcademy(ctx context.Context, id uuid.UUID) error
|
| 25 |
+
ListAcademy(ctx context.Context, accountId uuid.UUID, p repositories.Pagination) ([]entity.Academy, int64, error)
|
| 26 |
|
| 27 |
CreateMaterial(ctx context.Context, req dto.CreateMaterialRequest) (entity.AcademyMaterial, error)
|
| 28 |
GetMaterial(ctx context.Context, accountId uuid.UUID, academySlug string, materialSlug string) (entity.AcademyMaterial, error)
|
|
|
|
| 145 |
return s.academyRepo.DeleteAcademy(ctx, id)
|
| 146 |
}
|
| 147 |
|
| 148 |
+
func (s *academyService) ListAcademy(ctx context.Context, accountId uuid.UUID, p repositories.Pagination) ([]entity.Academy, int64, error) {
|
| 149 |
list, total, err := s.academyRepo.ListVisibleAcademy(ctx, accountId, &p)
|
| 150 |
return list, total, err
|
| 151 |
}
|
|
|
|
| 321 |
if err != nil {
|
| 322 |
return entity.AcademyContent{}, err
|
| 323 |
}
|
| 324 |
+
|
| 325 |
+
if err := s.academyRepo.Atomic(ctx, func(txRepo repositories.AcademyRepository) error {
|
| 326 |
+
existingAMP, _ := txRepo.GetMaterialProgress(ctx, accountId, material.AcademyId, material.Id)
|
| 327 |
+
ampID := existingAMP.Id
|
| 328 |
+
if ampID == uuid.Nil {
|
| 329 |
+
ampID = uuid.New()
|
| 330 |
+
}
|
| 331 |
+
matStatus := existingAMP.Status
|
| 332 |
+
if matStatus != entity.StatusFinished {
|
| 333 |
+
matStatus = entity.StatusInProgress
|
| 334 |
+
}
|
| 335 |
+
if _, err := txRepo.UpsertMaterialProgress(ctx, entity.AcademyMaterialProgress{
|
| 336 |
+
Id: ampID,
|
| 337 |
+
AccountId: accountId,
|
| 338 |
+
AcademyId: material.AcademyId,
|
| 339 |
+
MaterialId: material.Id,
|
| 340 |
+
Progress: existingAMP.Progress,
|
| 341 |
+
TotalCompletedContents: existingAMP.TotalCompletedContents,
|
| 342 |
+
Status: matStatus,
|
| 343 |
+
CompletedAt: existingAMP.CompletedAt,
|
| 344 |
+
}); err != nil {
|
| 345 |
+
return err
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
existingAP, _ := txRepo.GetAcademyProgress(ctx, accountId, material.AcademyId)
|
| 349 |
+
apID := existingAP.Id
|
| 350 |
+
if apID == uuid.Nil {
|
| 351 |
+
apID = uuid.New()
|
| 352 |
+
}
|
| 353 |
+
acadStatus := existingAP.Status
|
| 354 |
+
if acadStatus != entity.StatusFinished {
|
| 355 |
+
acadStatus = entity.StatusInProgress
|
| 356 |
+
}
|
| 357 |
+
if _, err := txRepo.UpsertAcademyProgress(ctx, entity.AcademyProgress{
|
| 358 |
+
Id: apID,
|
| 359 |
+
AccountId: accountId,
|
| 360 |
+
AcademyId: material.AcademyId,
|
| 361 |
+
Progress: existingAP.Progress,
|
| 362 |
+
TotalCompletedMaterials: existingAP.TotalCompletedMaterials,
|
| 363 |
+
Status: acadStatus,
|
| 364 |
+
CompletedAt: existingAP.CompletedAt,
|
| 365 |
+
}); err != nil {
|
| 366 |
+
return err
|
| 367 |
+
}
|
| 368 |
+
return nil
|
| 369 |
+
}); err != nil {
|
| 370 |
+
return entity.AcademyContent{}, err
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
return s.academyRepo.GetContentWithProgress(ctx, accountId, material.AcademyId, material.Id, order)
|
| 374 |
}
|
| 375 |
|
|
|
|
| 564 |
}
|
| 565 |
previews := make([]dto.MaterialPreview, len(mats))
|
| 566 |
for i, m := range mats {
|
| 567 |
+
previews[i] = dto.MaterialPreview{
|
| 568 |
+
Id: m.Id,
|
| 569 |
+
Title: m.Title,
|
| 570 |
+
Order: m.Order,
|
| 571 |
+
}
|
| 572 |
+
}
|
| 573 |
+
res := dto.AcademyPublicPreviewResponse{
|
| 574 |
+
Id: academy.Id,
|
| 575 |
+
Title: academy.Title,
|
| 576 |
+
Description: academy.Description,
|
| 577 |
+
ImageUrl: academy.ImageUrl,
|
| 578 |
+
Code: academy.Code,
|
| 579 |
+
RegisterStatus: 0,
|
| 580 |
+
Materials: previews,
|
| 581 |
}
|
|
|
|
| 582 |
return res, nil
|
| 583 |
}
|
| 584 |
return nil, http_error.UNAUTHORIZED
|