feat: update articles & articles_categories
This commit is contained in:
parent
8012896dfb
commit
64a91a1aef
|
|
@ -8,6 +8,7 @@ type ArticleCategories struct {
|
|||
Description string `json:"description" gorm:"type:varchar"`
|
||||
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
|
||||
ParentId *int `json:"parent_id" gorm:"type:int4"`
|
||||
Tags *string `json:"tags" gorm:"type:varchar"`
|
||||
Position *int `json:"position" gorm:"type:int4"`
|
||||
CreatedById *uint `json:"created_by_id" gorm:"type:int4"`
|
||||
StatusId int `json:"status_id" gorm:"type:int4;default:1"`
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import "time"
|
|||
|
||||
type ArticleCategoryDetails struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
|
||||
ArticleId int `json:"article_id" gorm:"type:int4"`
|
||||
ArticleId uint `json:"article_id" gorm:"type:int4"`
|
||||
CategoryId int `json:"category_id" gorm:"type:int4"`
|
||||
IsActive bool `json:"is_active" gorm:"type:bool"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ import (
|
|||
"go-humas-be/app/database/entity"
|
||||
res "go-humas-be/app/module/article_categories/response"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ArticleCategoriesResponseMapper(articleCategoriesReq *entity.ArticleCategories) (articleCategoriesRes *res.ArticleCategoriesResponse) {
|
||||
func ArticleCategoriesResponseMapper(articleCategoriesReq *entity.ArticleCategories, host string) (articleCategoriesRes *res.ArticleCategoriesResponse) {
|
||||
if articleCategoriesReq != nil {
|
||||
articleCategoriesRes = &res.ArticleCategoriesResponse{
|
||||
ID: articleCategoriesReq.ID,
|
||||
Title: articleCategoriesReq.Title,
|
||||
Description: articleCategoriesReq.Description,
|
||||
ThumbnailPath: articleCategoriesReq.ThumbnailPath,
|
||||
ThumbnailUrl: "/article-categories/thumbnail/viewer/" + strconv.Itoa(int(articleCategoriesReq.ID)),
|
||||
ParentId: articleCategoriesReq.ParentId,
|
||||
CreatedById: articleCategoriesReq.CreatedById,
|
||||
StatusId: articleCategoriesReq.StatusId,
|
||||
|
|
@ -23,6 +23,15 @@ func ArticleCategoriesResponseMapper(articleCategoriesReq *entity.ArticleCategor
|
|||
CreatedAt: articleCategoriesReq.CreatedAt,
|
||||
UpdatedAt: articleCategoriesReq.UpdatedAt,
|
||||
}
|
||||
|
||||
if articleCategoriesReq.Tags != nil {
|
||||
tagsValue := *articleCategoriesReq.Tags
|
||||
articleCategoriesRes.Tags = strings.Split(tagsValue, ",")
|
||||
}
|
||||
|
||||
if articleCategoriesRes.ThumbnailPath != nil {
|
||||
articleCategoriesRes.ThumbnailUrl = host + "/article-categories/thumbnail/viewer/" + strconv.Itoa(int(articleCategoriesReq.ID))
|
||||
}
|
||||
}
|
||||
return articleCategoriesRes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ type ArticleCategoriesCreateRequest struct {
|
|||
Title string `json:"title" validate:"required"`
|
||||
Description string `json:"description" validate:"required"`
|
||||
StatusId int `json:"statusId" validate:"required"`
|
||||
Tags *string `json:"tags"`
|
||||
ParentId *int `json:"parentId"`
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ func (req ArticleCategoriesCreateRequest) ToEntity() *entity.ArticleCategories {
|
|||
return &entity.ArticleCategories{
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
Tags: req.Tags,
|
||||
ParentId: req.ParentId,
|
||||
StatusId: req.StatusId,
|
||||
}
|
||||
|
|
@ -41,6 +43,7 @@ type ArticleCategoriesUpdateRequest struct {
|
|||
Title string `json:"title" validate:"required"`
|
||||
Description string `json:"description" validate:"required"`
|
||||
StatusId int `json:"statusId" validate:"required"`
|
||||
Tags *string `json:"tags"`
|
||||
ParentId *int `json:"parentId"`
|
||||
IsPublish *bool `json:"isPublish"`
|
||||
PublishedAt *time.Time `json:"publishedAt"`
|
||||
|
|
@ -52,6 +55,7 @@ func (req ArticleCategoriesUpdateRequest) ToEntity() *entity.ArticleCategories {
|
|||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
ParentId: req.ParentId,
|
||||
Tags: req.Tags,
|
||||
StatusId: req.StatusId,
|
||||
IsPublish: req.IsPublish,
|
||||
PublishedAt: req.PublishedAt,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ type ArticleCategoriesResponse struct {
|
|||
ID uint `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
ThumbnailPath *string `json:"thumbnailPath"`
|
||||
ThumbnailUrl string `json:"thumbnailUrl"`
|
||||
Tags []string `json:"tags"`
|
||||
ThumbnailPath *string `json:"thumbnailPath"`
|
||||
ParentId *int `json:"parentId"`
|
||||
CreatedById *uint `json:"createdById"`
|
||||
StatusId int `json:"statusId"`
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"go-humas-be/app/module/article_categories/request"
|
||||
"go-humas-be/app/module/article_categories/response"
|
||||
usersRepository "go-humas-be/app/module/users/repository"
|
||||
config "go-humas-be/config/config"
|
||||
minioStorage "go-humas-be/config/config"
|
||||
"go-humas-be/utils/paginator"
|
||||
utilSvc "go-humas-be/utils/service"
|
||||
|
|
@ -30,6 +31,7 @@ type articleCategoriesService struct {
|
|||
UsersRepo usersRepository.UsersRepository
|
||||
MinioStorage *minioStorage.MinioStorage
|
||||
Log zerolog.Logger
|
||||
Cfg *config.Config
|
||||
}
|
||||
|
||||
// ArticleCategoriesService define interface of IArticleCategoriesService
|
||||
|
|
@ -44,13 +46,14 @@ type ArticleCategoriesService interface {
|
|||
}
|
||||
|
||||
// NewArticleCategoriesService init ArticleCategoriesService
|
||||
func NewArticleCategoriesService(repo repository.ArticleCategoriesRepository, usersRepo usersRepository.UsersRepository, minioStorage *minioStorage.MinioStorage, log zerolog.Logger) ArticleCategoriesService {
|
||||
func NewArticleCategoriesService(repo repository.ArticleCategoriesRepository, usersRepo usersRepository.UsersRepository, minioStorage *minioStorage.MinioStorage, log zerolog.Logger, cfg *config.Config) ArticleCategoriesService {
|
||||
|
||||
return &articleCategoriesService{
|
||||
Repo: repo,
|
||||
UsersRepo: usersRepo,
|
||||
MinioStorage: minioStorage,
|
||||
Log: log,
|
||||
Cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,8 +64,10 @@ func (_i *articleCategoriesService) All(req request.ArticleCategoriesQueryReques
|
|||
return
|
||||
}
|
||||
|
||||
host := _i.Cfg.App.Domain
|
||||
port := _i.Cfg.App.ExternalPort
|
||||
for _, result := range results {
|
||||
articleCategoriess = append(articleCategoriess, mapper.ArticleCategoriesResponseMapper(result))
|
||||
articleCategoriess = append(articleCategoriess, mapper.ArticleCategoriesResponseMapper(result, host+port))
|
||||
}
|
||||
|
||||
return
|
||||
|
|
@ -73,8 +78,9 @@ func (_i *articleCategoriesService) Show(id uint) (articleCategories *response.A
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mapper.ArticleCategoriesResponseMapper(result), nil
|
||||
host := _i.Cfg.App.Domain
|
||||
port := _i.Cfg.App.ExternalPort
|
||||
return mapper.ArticleCategoriesResponseMapper(result, host+port), nil
|
||||
}
|
||||
|
||||
func (_i *articleCategoriesService) Save(req request.ArticleCategoriesCreateRequest, authToken string) (articleCategories *entity.ArticleCategories, err error) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type ArticleCategoryDetailsQueryRequest struct {
|
|||
}
|
||||
|
||||
type ArticleCategoryDetailsCreateRequest struct {
|
||||
ArticleId int `json:"article_id" validate:"required"`
|
||||
ArticleId uint `json:"article_id" validate:"required"`
|
||||
CategoryId int `json:"category_id" validate:"required"`
|
||||
IsActive bool `json:"is_active" validate:"required"`
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ func (req ArticleCategoryDetailsCreateRequest) ToEntity() *entity.ArticleCategor
|
|||
|
||||
type ArticleCategoryDetailsUpdateRequest struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
ArticleId int `json:"article_id" validate:"required"`
|
||||
ArticleId uint `json:"article_id" validate:"required"`
|
||||
CategoryId int `json:"category_id" validate:"required"`
|
||||
IsActive bool `json:"is_active" validate:"required"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
|
|
|||
|
|
@ -13,15 +13,12 @@ import (
|
|||
|
||||
func ArticlesResponseMapper(
|
||||
log zerolog.Logger,
|
||||
host string,
|
||||
articlesReq *entity.Articles,
|
||||
articleCategoriesRepo articleCategoriesRepository.ArticleCategoriesRepository,
|
||||
articleFilesRepo articleFilesRepository.ArticleFilesRepository,
|
||||
usersRepo usersRepository.UsersRepository,
|
||||
) (articlesRes *res.ArticlesResponse) {
|
||||
thumbnailUrl := "/articles/thumbnail/viewer/"
|
||||
if articlesReq.ThumbnailName != nil {
|
||||
thumbnailUrl += *articlesReq.ThumbnailName
|
||||
}
|
||||
|
||||
createdByName := ""
|
||||
if articlesReq.CreatedById != nil {
|
||||
|
|
@ -56,7 +53,6 @@ func ArticlesResponseMapper(
|
|||
HtmlDescription: articlesReq.HtmlDescription,
|
||||
TypeId: articlesReq.TypeId,
|
||||
Tags: articlesReq.Tags,
|
||||
ThumbnailUrl: thumbnailUrl,
|
||||
CategoryId: articlesReq.CategoryId,
|
||||
CategoryName: categoryName,
|
||||
PageUrl: articlesReq.PageUrl,
|
||||
|
|
@ -73,6 +69,10 @@ func ArticlesResponseMapper(
|
|||
UpdatedAt: articlesReq.UpdatedAt,
|
||||
ArticleFiles: articleFilesArr,
|
||||
}
|
||||
|
||||
if articlesReq.ThumbnailName != nil {
|
||||
articlesRes.ThumbnailUrl = host + "/articles/thumbnail/viewer/" + *articlesReq.ThumbnailName
|
||||
}
|
||||
}
|
||||
|
||||
return articlesRes
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ type ArticlesCreateRequest struct {
|
|||
Description string `json:"description" validate:"required"`
|
||||
HtmlDescription string `json:"htmlDescription" validate:"required"`
|
||||
CategoryId int `json:"categoryId" validate:"required"`
|
||||
CategoryIds string `json:"categoryIds" validate:"required"`
|
||||
TypeId int `json:"typeId" validate:"required"`
|
||||
Tags string `json:"tags" validate:"required"`
|
||||
OldId *uint `json:"oldId"`
|
||||
|
|
|
|||
|
|
@ -2,17 +2,21 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/rs/zerolog"
|
||||
"go-humas-be/app/database/entity"
|
||||
articleCategoriesRepository "go-humas-be/app/module/article_categories/repository"
|
||||
articleCategoryDetailsRepository "go-humas-be/app/module/article_category_details/repository"
|
||||
articleCategoryDetailsReq "go-humas-be/app/module/article_category_details/request"
|
||||
articleFilesRepository "go-humas-be/app/module/article_files/repository"
|
||||
"go-humas-be/app/module/articles/mapper"
|
||||
"go-humas-be/app/module/articles/repository"
|
||||
"go-humas-be/app/module/articles/request"
|
||||
"go-humas-be/app/module/articles/response"
|
||||
usersRepository "go-humas-be/app/module/users/repository"
|
||||
config "go-humas-be/config/config"
|
||||
minioStorage "go-humas-be/config/config"
|
||||
"go-humas-be/utils/paginator"
|
||||
utilSvc "go-humas-be/utils/service"
|
||||
|
|
@ -31,7 +35,9 @@ type articlesService struct {
|
|||
Repo repository.ArticlesRepository
|
||||
ArticleCategoriesRepo articleCategoriesRepository.ArticleCategoriesRepository
|
||||
ArticleFilesRepo articleFilesRepository.ArticleFilesRepository
|
||||
ArticleCategoryDetailsRepo articleCategoryDetailsRepository.ArticleCategoryDetailsRepository
|
||||
Log zerolog.Logger
|
||||
Cfg *config.Config
|
||||
UsersRepo usersRepository.UsersRepository
|
||||
MinioStorage *minioStorage.MinioStorage
|
||||
}
|
||||
|
|
@ -51,8 +57,10 @@ type ArticlesService interface {
|
|||
func NewArticlesService(
|
||||
repo repository.ArticlesRepository,
|
||||
articleCategoriesRepo articleCategoriesRepository.ArticleCategoriesRepository,
|
||||
articleCategoryDetailsRepo articleCategoryDetailsRepository.ArticleCategoryDetailsRepository,
|
||||
articleFilesRepo articleFilesRepository.ArticleFilesRepository,
|
||||
log zerolog.Logger,
|
||||
cfg *config.Config,
|
||||
usersRepo usersRepository.UsersRepository,
|
||||
minioStorage *minioStorage.MinioStorage,
|
||||
) ArticlesService {
|
||||
|
|
@ -60,10 +68,12 @@ func NewArticlesService(
|
|||
return &articlesService{
|
||||
Repo: repo,
|
||||
ArticleCategoriesRepo: articleCategoriesRepo,
|
||||
ArticleCategoryDetailsRepo: articleCategoryDetailsRepo,
|
||||
ArticleFilesRepo: articleFilesRepo,
|
||||
Log: log,
|
||||
UsersRepo: usersRepo,
|
||||
MinioStorage: minioStorage,
|
||||
Cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,8 +88,11 @@ func (_i *articlesService) All(req request.ArticlesQueryRequest) (articless []*r
|
|||
Format(time.RFC3339)).Str("Service:articlesService", "Methods:All").
|
||||
Interface("results", results).Msg("")
|
||||
|
||||
host := _i.Cfg.App.Domain
|
||||
port := _i.Cfg.App.ExternalPort
|
||||
|
||||
for _, result := range results {
|
||||
articleRes := mapper.ArticlesResponseMapper(_i.Log, result, _i.ArticleCategoriesRepo, _i.ArticleFilesRepo, _i.UsersRepo)
|
||||
articleRes := mapper.ArticlesResponseMapper(_i.Log, host+port, result, _i.ArticleCategoriesRepo, _i.ArticleFilesRepo, _i.UsersRepo)
|
||||
articless = append(articless, articleRes)
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +105,10 @@ func (_i *articlesService) Show(id uint) (articles *response.ArticlesResponse, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return mapper.ArticlesResponseMapper(_i.Log, result, _i.ArticleCategoriesRepo, _i.ArticleFilesRepo, _i.UsersRepo), nil
|
||||
host := _i.Cfg.App.Domain
|
||||
port := _i.Cfg.App.ExternalPort
|
||||
|
||||
return mapper.ArticlesResponseMapper(_i.Log, host+port, result, _i.ArticleCategoriesRepo, _i.ArticleFilesRepo, _i.UsersRepo), nil
|
||||
}
|
||||
|
||||
func (_i *articlesService) Save(req request.ArticlesCreateRequest, authToken string) (articles *entity.Articles, err error) {
|
||||
|
|
@ -102,7 +118,41 @@ func (_i *articlesService) Save(req request.ArticlesCreateRequest, authToken str
|
|||
createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
newReq.CreatedById = &createdBy.ID
|
||||
|
||||
return _i.Repo.Create(newReq)
|
||||
saveArticleRepo, err := _i.Repo.Create(newReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var categoryIds []string
|
||||
if req.CategoryIds != "" {
|
||||
categoryIds = strings.Split(req.CategoryIds, ",")
|
||||
}
|
||||
|
||||
for categoryId := range categoryIds {
|
||||
findCategory, err := _i.ArticleCategoriesRepo.FindOne(uint(categoryId))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if findCategory != nil {
|
||||
return nil, errors.New("category not found")
|
||||
}
|
||||
|
||||
categoryReq := articleCategoryDetailsReq.ArticleCategoryDetailsCreateRequest{
|
||||
ArticleId: saveArticleRepo.ID,
|
||||
CategoryId: categoryId,
|
||||
IsActive: true,
|
||||
}
|
||||
newCategoryReq := categoryReq.ToEntity()
|
||||
|
||||
err = _i.ArticleCategoryDetailsRepo.Create(newCategoryReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return saveArticleRepo, nil
|
||||
}
|
||||
|
||||
func (_i *articlesService) SaveThumbnail(c *fiber.Ctx) (err error) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
name = "Fiber starter"
|
||||
host = "http://38.47.180.165"
|
||||
port = ":8800"
|
||||
domain = "https://38.47.180.165"
|
||||
domain = "http://38.47.180.165"
|
||||
external-port = ":8802"
|
||||
idle-timeout = 5 # As seconds
|
||||
print-routes = false
|
||||
|
|
@ -13,7 +13,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>
|
||||
migrate = false
|
||||
migrate = true
|
||||
seed = false
|
||||
|
||||
[logger]
|
||||
|
|
|
|||
|
|
@ -6125,6 +6125,9 @@ const docTemplate = `{
|
|||
"statusId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
|
|
@ -6157,6 +6160,9 @@ const docTemplate = `{
|
|||
"statusId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
|
|
@ -6302,6 +6308,7 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"required": [
|
||||
"categoryId",
|
||||
"categoryIds",
|
||||
"description",
|
||||
"htmlDescription",
|
||||
"slug",
|
||||
|
|
@ -6313,6 +6320,9 @@ const docTemplate = `{
|
|||
"categoryId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"categoryIds": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6114,6 +6114,9 @@
|
|||
"statusId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
|
|
@ -6146,6 +6149,9 @@
|
|||
"statusId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"tags": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
|
|
@ -6291,6 +6297,7 @@
|
|||
"type": "object",
|
||||
"required": [
|
||||
"categoryId",
|
||||
"categoryIds",
|
||||
"description",
|
||||
"htmlDescription",
|
||||
"slug",
|
||||
|
|
@ -6302,6 +6309,9 @@
|
|||
"categoryId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"categoryIds": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ definitions:
|
|||
type: integer
|
||||
statusId:
|
||||
type: integer
|
||||
tags:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
required:
|
||||
|
|
@ -47,6 +49,8 @@ definitions:
|
|||
type: string
|
||||
statusId:
|
||||
type: integer
|
||||
tags:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
required:
|
||||
|
|
@ -155,6 +159,8 @@ definitions:
|
|||
properties:
|
||||
categoryId:
|
||||
type: integer
|
||||
categoryIds:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
htmlDescription:
|
||||
|
|
@ -171,6 +177,7 @@ definitions:
|
|||
type: integer
|
||||
required:
|
||||
- categoryId
|
||||
- categoryIds
|
||||
- description
|
||||
- htmlDescription
|
||||
- slug
|
||||
|
|
|
|||
Loading…
Reference in New Issue