feat: ads log

This commit is contained in:
ericprd 2025-03-17 22:19:17 +08:00
parent ee8e8e140d
commit c0dcdb77fa
19 changed files with 276 additions and 4 deletions

11
database/log_ads_model.go Normal file
View File

@ -0,0 +1,11 @@
package database
import "time"
type LogAds struct {
ID string `gorm:"primaryKey;not null" json:"id"`
AdsID string `gorm:"not null" json:"ads_id"`
UserID string `gorm:"not null" json:"user_id"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}

View File

@ -0,0 +1,11 @@
package database
import "time"
type LogNews struct {
ID string `gorm:"primaryKey;not null" json:"id"`
NewsID string `gorm:"not null" json:"news_id"`
UserID string `gorm:"not null" json:"user_id"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}

View File

@ -55,5 +55,7 @@ func (db *DB) Migrate() error {
&Tag{}, &Tag{},
&Category{}, &Category{},
&Ads{}, &Ads{},
&LogAds{},
&LogNews{},
) )
} }

View File

@ -0,0 +1,20 @@
package logrepository
import (
"legalgo-BE-go/database"
"github.com/google/uuid"
)
func (a *accessor) CreateLogAds(adsID, userID string) error {
spec := database.LogAds{
ID: uuid.NewString(),
AdsID: adsID,
UserID: userID,
}
if err := a.db.Create(&spec).Error; err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,21 @@
package logrepository
import (
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (a *accessor) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
var ads []adsdomain.Ads
// if err := a.db.Find(&ads, "user_id = ?", userID).Error; err != nil {
// return ads, err
// }
if err := a.db.
Joins("JOIN log_ads ON ads.id = log_ads.ads_id").
Find(&ads, "log_ads.user_id = ?", userID).Error; err != nil {
return ads, err
}
return ads, nil
}

View File

@ -0,0 +1,19 @@
package logrepository
import (
"legalgo-BE-go/database"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
type accessor struct {
db *database.DB
}
type Log interface {
CreateLogAds(adsID, userID string) error
GetAllLogAds(string) ([]adsdomain.Ads, error)
}
func New(db *database.DB) Log {
return &accessor{db}
}

View File

@ -3,6 +3,7 @@ package repository
import ( import (
adsrepository "legalgo-BE-go/internal/accessor/ads" adsrepository "legalgo-BE-go/internal/accessor/ads"
categoryrepository "legalgo-BE-go/internal/accessor/category" categoryrepository "legalgo-BE-go/internal/accessor/category"
logrepository "legalgo-BE-go/internal/accessor/log"
newsrepository "legalgo-BE-go/internal/accessor/news" newsrepository "legalgo-BE-go/internal/accessor/news"
"legalgo-BE-go/internal/accessor/oss" "legalgo-BE-go/internal/accessor/oss"
redisaccessor "legalgo-BE-go/internal/accessor/redis" redisaccessor "legalgo-BE-go/internal/accessor/redis"
@ -26,4 +27,5 @@ var Module = fx.Module("repository", fx.Provide(
newsrepository.New, newsrepository.New,
oss.New, oss.New,
adsrepository.New, adsrepository.New,
logrepository.New,
)) ))

View File

@ -0,0 +1,68 @@
package logshttp
import (
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
logsdomain "legalgo-BE-go/internal/domain/logs"
logssvc "legalgo-BE-go/internal/services/logs"
usersvc "legalgo-BE-go/internal/services/user"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http"
"github.com/go-chi/chi/v5"
)
func CreateLogAds(
router chi.Router,
userSvc usersvc.User,
logsSvc logssvc.Log,
) {
router.With(authmiddleware.Authorize()).Post("/logs/ads", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
userDetail, err := utils.GetTokenDetail(r)
if err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrUnauthorized.Code,
response.ErrUnauthorized.HttpCode,
"unauthorized",
)
return
}
var spec logsdomain.LogsRequest
if err := utils.UnmarshalBody(r, &spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"failed unmarshal body",
)
return
}
if err := logsSvc.CreateLogAds(spec.AdsID, userDetail.ID); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "logs ads recorded successfully",
})
})
}

View File

@ -0,0 +1,37 @@
package logshttp
import (
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
logssvc "legalgo-BE-go/internal/services/logs"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http"
"github.com/go-chi/chi/v5"
)
func GetUserAds(
router chi.Router,
logSvc logssvc.Log,
) {
router.With(authmiddleware.Authorize()).Get("/logs/ads", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
userDetail, err := utils.GetTokenDetail(r)
subsPlan, err := logSvc.GetAllLogAds(userDetail.ID)
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, subsPlan)
})
}

View File

@ -0,0 +1,8 @@
package logshttp
import "go.uber.org/fx"
var Module = fx.Module("logs-http", fx.Invoke(
CreateLogAds,
GetUserAds,
))

View File

@ -3,6 +3,7 @@ package internalhttp
import ( import (
adshttp "legalgo-BE-go/internal/api/http/ads" adshttp "legalgo-BE-go/internal/api/http/ads"
categoryhttp "legalgo-BE-go/internal/api/http/category" categoryhttp "legalgo-BE-go/internal/api/http/category"
logshttp "legalgo-BE-go/internal/api/http/logs"
newshttp "legalgo-BE-go/internal/api/http/news" newshttp "legalgo-BE-go/internal/api/http/news"
osshttp "legalgo-BE-go/internal/api/http/oss" osshttp "legalgo-BE-go/internal/api/http/oss"
staffhttp "legalgo-BE-go/internal/api/http/staff" staffhttp "legalgo-BE-go/internal/api/http/staff"
@ -33,6 +34,7 @@ var Module = fx.Module("router",
userhttp.Module, userhttp.Module,
subscribehttp.Module, subscribehttp.Module,
adshttp.Module, adshttp.Module,
logshttp.Module,
) )
func initRouter() chi.Router { func initRouter() chi.Router {

View File

@ -0,0 +1,14 @@
package logsdomain
import (
adsdomain "legalgo-BE-go/internal/domain/ads"
)
type LogsRequest struct {
AdsID string `json:"ads_id" validate:"required"`
}
type LogResponse struct {
ID string `json:"id"`
News []adsdomain.Ads `json:"news"`
}

View File

@ -0,0 +1,11 @@
package logssvc
import "fmt"
func (i *impl) CreateLogAds(adsID, userID string) error {
if err := i.logsRepo.CreateLogAds(adsID, userID); err != nil {
return fmt.Errorf("failed to create ads log: %v", err)
}
return nil
}

View File

@ -0,0 +1,20 @@
package logssvc
import (
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (i *impl) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
var (
logs []adsdomain.Ads
err error
)
logs, err = i.logsRepo.GetAllLogAds(userID)
if err != nil {
return logs, fmt.Errorf("failed to get user logs ads: %v", err)
}
return logs, nil
}

View File

@ -0,0 +1,23 @@
package logssvc
import (
logrepository "legalgo-BE-go/internal/accessor/log"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
type impl struct {
logsRepo logrepository.Log
}
type Log interface {
CreateLogAds(adsID, userID string) error
GetAllLogAds(string) ([]adsdomain.Ads, error)
}
func New(
logsRepo logrepository.Log,
) Log {
return &impl{
logsRepo,
}
}

View File

@ -3,6 +3,7 @@ package services
import ( import (
adssvc "legalgo-BE-go/internal/services/ads" adssvc "legalgo-BE-go/internal/services/ads"
categorysvc "legalgo-BE-go/internal/services/category" categorysvc "legalgo-BE-go/internal/services/category"
logssvc "legalgo-BE-go/internal/services/logs"
newssvc "legalgo-BE-go/internal/services/news" newssvc "legalgo-BE-go/internal/services/news"
"legalgo-BE-go/internal/services/oss" "legalgo-BE-go/internal/services/oss"
staffsvc "legalgo-BE-go/internal/services/staffsvc" staffsvc "legalgo-BE-go/internal/services/staffsvc"
@ -25,5 +26,6 @@ var Module = fx.Module("services",
oss.NewOSSService, oss.NewOSSService,
usersvc.New, usersvc.New,
adssvc.New, adssvc.New,
logssvc.New,
), ),
) )

View File

@ -4,8 +4,8 @@ import (
userdomain "legalgo-BE-go/internal/domain/user" userdomain "legalgo-BE-go/internal/domain/user"
) )
func (i *impl) GetUserProfile(email string) (*userdomain.UserProfile, error) { func (i *impl) GetUserProfile(id string) (*userdomain.UserProfile, error) {
user, err := i.userRepo.GetUserProfile(email) user, err := i.userRepo.GetUserProfile(id)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -50,7 +50,7 @@ func (i *impl) RegisterUser(spec userdomain.UserRegister) (string, error) {
err = i.userRepo.CreateUser(user) err = i.userRepo.CreateUser(user)
if err != nil { if err != nil {
return "", fmt.Errorf(err.Error()) return "", fmt.Errorf("create user failed: %v", err)
} }
authToken := authdomain.AuthToken{ authToken := authdomain.AuthToken{
@ -62,7 +62,7 @@ func (i *impl) RegisterUser(spec userdomain.UserRegister) (string, error) {
token, err := utils.GenerateToken(authToken) token, err := utils.GenerateToken(authToken)
if err != nil { if err != nil {
return "", fmt.Errorf(err.Error()) return "", fmt.Errorf("generate token failed: %v", err)
} }
return token, nil return token, nil
} }

View File

@ -18,6 +18,7 @@ var (
ErrUnauthorized = &ErrorCode{Code: "UNAUTHORIZED", Message: "UNAUTHORIZED", HttpCode: http.StatusUnauthorized} ErrUnauthorized = &ErrorCode{Code: "UNAUTHORIZED", Message: "UNAUTHORIZED", HttpCode: http.StatusUnauthorized}
ErrDBRequest = &ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest} ErrDBRequest = &ErrorCode{Code: "BAD_DB_REQUEST", Message: "DB_ERROR", HttpCode: http.StatusBadRequest}
ErrExpiryToken = &ErrorCode{Code: "EXPIRED_TOKEN", Message: "EXPIRED_TOKEN", HttpCode: http.StatusUnauthorized} ErrExpiryToken = &ErrorCode{Code: "EXPIRED_TOKEN", Message: "EXPIRED_TOKEN", HttpCode: http.StatusUnauthorized}
ErrNotFound = &ErrorCode{Code: "NOT_FOUND", Message: "NOT_FOUND", HttpCode: http.StatusNotFound}
// 5xx // 5xx
ErrMarshal = &ErrorCode{Code: "FAILED_MARSHAL", Message: "FAILED_MARSHAL_BODY", HttpCode: http.StatusInternalServerError} ErrMarshal = &ErrorCode{Code: "FAILED_MARSHAL", Message: "FAILED_MARSHAL_BODY", HttpCode: http.StatusInternalServerError}