feat: update go scheduler, article
This commit is contained in:
parent
4ca1051173
commit
95ce943240
|
|
@ -27,6 +27,7 @@ type Articles struct {
|
|||
PublishedAt *time.Time `json:"published_at" gorm:"type:timestamp"`
|
||||
IsDraft *bool `json:"is_draft" gorm:"type:bool;default:false"`
|
||||
DraftedAt *time.Time `json:"drafted_at" gorm:"type:timestamp"`
|
||||
PublishSchedule *string `json:"publish_schedule" gorm:"type:varchar"`
|
||||
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ func (_i *ArticlesRouter) RegisterArticlesRoutes() {
|
|||
router.Put("/:id", articlesController.Update)
|
||||
router.Post("/thumbnail/:id", articlesController.SaveThumbnail)
|
||||
router.Get("/thumbnail/viewer/:thumbnailName", articlesController.Viewer)
|
||||
router.Post("/publish-scheduling", articlesController.PublishScheduling)
|
||||
router.Delete("/:id", articlesController.Delete)
|
||||
router.Get("/statistic/summary", articlesController.SummaryStats)
|
||||
router.Get("/statistic/user-levels", articlesController.ArticlePerUserLevelStats)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type ArticlesController interface {
|
|||
SummaryStats(c *fiber.Ctx) error
|
||||
ArticlePerUserLevelStats(c *fiber.Ctx) error
|
||||
ArticleMonthlyStats(c *fiber.Ctx) error
|
||||
PublishScheduling(c *fiber.Ctx) error
|
||||
}
|
||||
|
||||
func NewArticlesController(articlesService service.ArticlesService) ArticlesController {
|
||||
|
|
@ -328,3 +329,34 @@ func (_i *articlesController) ArticleMonthlyStats(c *fiber.Ctx) error {
|
|||
Data: response,
|
||||
})
|
||||
}
|
||||
|
||||
// PublishScheduling Articles
|
||||
// @Summary PublishScheduling Articles
|
||||
// @Description API for Publish Schedule of Article
|
||||
// @Tags Articles
|
||||
// @Security Bearer
|
||||
// @Param Authorization header string true "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param id query int false "article id"
|
||||
// @Param date query string false "publish date"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /articles/publish-scheduling [post]
|
||||
func (_i *articlesController) PublishScheduling(c *fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Query("id"), 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
date := c.Query("date")
|
||||
|
||||
err = _i.articlesService.PublishScheduling(uint(id), date)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Publish Scheduling of Articles successfully saved"},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ type articlesRepository struct {
|
|||
// ArticlesRepository define interface of IArticlesRepository
|
||||
type ArticlesRepository interface {
|
||||
GetAll(req request.ArticlesQueryRequest) (articless []*entity.Articles, paging paginator.Pagination, err error)
|
||||
GetAllPublishSchedule() (articless []*entity.Articles, err error)
|
||||
FindOne(id uint) (articles *entity.Articles, err error)
|
||||
FindByFilename(thumbnailName string) (articleReturn *entity.Articles, err error)
|
||||
Create(articles *entity.Articles) (articleReturn *entity.Articles, err error)
|
||||
|
|
@ -102,6 +103,14 @@ func (_i *articlesRepository) GetAll(req request.ArticlesQueryRequest) (articles
|
|||
return
|
||||
}
|
||||
|
||||
func (_i *articlesRepository) GetAllPublishSchedule() (articles []*entity.Articles, err error) {
|
||||
err = _i.DB.DB.Where("publish_schedule IS NOT NULL").Find(&articles).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
func (_i *articlesRepository) FindOne(id uint) (articles *entity.Articles, err error) {
|
||||
if err := _i.DB.DB.First(&articles, id).Error; err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ type ArticlesService interface {
|
|||
SummaryStats(authToken string) (summaryStats *response.ArticleSummaryStats, err error)
|
||||
ArticlePerUserLevelStats(authToken string, startDate *string, endDate *string) (articlePerUserLevelStats []*response.ArticlePerUserLevelStats, err error)
|
||||
ArticleMonthlyStats(authToken string, year *int) (articleMonthlyStats []*response.ArticleMonthlyStats, err error)
|
||||
PublishScheduling(id uint, publishSchedule string) error
|
||||
ExecuteScheduling() error
|
||||
}
|
||||
|
||||
// NewArticlesService init ArticlesService
|
||||
|
|
@ -180,6 +182,7 @@ func (_i *articlesService) Save(req request.ArticlesCreateRequest, authToken str
|
|||
// Approval
|
||||
statusIdOne := 1
|
||||
statusIdTwo := 2
|
||||
isPublishFalse := false
|
||||
createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if createdBy != nil && *createdBy.UserLevel.IsApprovalActive == true {
|
||||
newReq.NeedApprovalFrom = nil
|
||||
|
|
@ -187,6 +190,8 @@ func (_i *articlesService) Save(req request.ArticlesCreateRequest, authToken str
|
|||
} else {
|
||||
newReq.NeedApprovalFrom = &userParentLevelId
|
||||
newReq.StatusId = &statusIdOne
|
||||
newReq.IsPublish = &isPublishFalse
|
||||
newReq.PublishedAt = nil
|
||||
}
|
||||
|
||||
saveArticleRes, err := _i.Repo.Create(newReq)
|
||||
|
|
@ -554,6 +559,56 @@ func (_i *articlesService) UpdateApproval(id uint, statusId int, userLevelId int
|
|||
return
|
||||
}
|
||||
|
||||
func (_i *articlesService) PublishScheduling(id uint, publishSchedule string) error {
|
||||
result, err := _i.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result.PublishSchedule = &publishSchedule
|
||||
|
||||
return _i.Repo.Update(id, result)
|
||||
}
|
||||
|
||||
func (_i *articlesService) ExecuteScheduling() error {
|
||||
articles, err := _i.Repo.GetAllPublishSchedule()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
layout := "2006-01-02"
|
||||
now := time.Now()
|
||||
today := now.Truncate(24 * time.Hour)
|
||||
|
||||
for _, article := range articles { // Looping setiap artikel
|
||||
if article.PublishSchedule == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
parsedDate, err := time.Parse(layout, *article.PublishSchedule)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if parsedDate.Equal(today) {
|
||||
isPublish := true
|
||||
statusIdTwo := 2
|
||||
|
||||
article.PublishSchedule = nil
|
||||
article.IsPublish = &isPublish
|
||||
article.PublishedAt = &now
|
||||
article.StatusId = &statusIdTwo
|
||||
|
||||
if err := _i.Repo.Update(article.ID, article); err != nil {
|
||||
_i.Log.Info().Str("timestamp", time.Now().
|
||||
Format(time.RFC3339)).Str("Service:articlesService", "Methods:ExecuteScheduling").
|
||||
Interface("Failed to publish Article ID : ", article.ID).Msg("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func getFileExtension(filename string) string {
|
||||
// split file name
|
||||
parts := strings.Split(filename, ".")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ body-limit = 1048576000 # "100 * 1024 * 1024"
|
|||
[db.postgres]
|
||||
dsn = "postgresql://humas_user:HumasDB@2024@38.47.180.165:5432/humas_db" # <driver>://<username>:<password>@<host>:<port>/<database>
|
||||
log-mode = "NONE"
|
||||
migrate = false
|
||||
migrate = true
|
||||
seed = false
|
||||
|
||||
[logger]
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"go-humas-be/app/database"
|
||||
"go-humas-be/app/database/seeds"
|
||||
md "go-humas-be/app/middleware"
|
||||
articlesService "go-humas-be/app/module/articles/service"
|
||||
"go-humas-be/app/router"
|
||||
"go-humas-be/config/config"
|
||||
"go-humas-be/utils/response"
|
||||
|
|
@ -149,12 +150,16 @@ func Start(lifecycle fx.Lifecycle, cfg *config.Config, fiber *fiber.App, router
|
|||
)
|
||||
}
|
||||
|
||||
func RunScheduling(lifecycle fx.Lifecycle) *gocron.Scheduler {
|
||||
func RunScheduling(lifecycle fx.Lifecycle, articleService articlesService.ArticlesService) *gocron.Scheduler {
|
||||
scheduler := gocron.NewScheduler(time.UTC)
|
||||
|
||||
// Tambahkan tugas yang berjalan setiap 10 detik
|
||||
scheduler.Every(1).Minutes().SingletonMode().Do(func() {
|
||||
fmt.Println("Run Scheduler", time.Now())
|
||||
err := articleService.ExecuteScheduling()
|
||||
if err != nil {
|
||||
fmt.Println("Scheduler Got An Error", time.Now())
|
||||
}
|
||||
})
|
||||
|
||||
// Menambahkan lifecycle hooks di Fx
|
||||
|
|
|
|||
Loading…
Reference in New Issue