blog/internal/service/ArticleService.go

224 lines
6.7 KiB
Go

package service
import (
"blog/internal/consts"
"blog/internal/model/admin"
"blog/internal/model/blog"
"blog/internal/model/vo"
"blog/third_party/database"
"context"
"errors"
"log"
"strconv"
"time"
"github.com/google/uuid"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
)
type articleService struct {
}
var ArticleService articleService
func (*articleService) InitArticleData() {
var articleSlice []blog.BlogArticle
result := database.GormTemplate.Where("state = ?", consts.ARTICLE_STATE_PUBLISH).Find(&articleSlice)
log.Println("文章初始化数据加载量:", result.RowsAffected)
ctx := context.Background()
for _, article := range articleSlice {
// log.Println(article)
publishTime := article.PublishTime
err := database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
if err != nil {
log.Println(err)
}
}
type viewRecord struct {
RelId string
Counts int
}
var records []viewRecord
database.GormTemplate.Table("blog_view_record").Select("rel_id ,count(1) counts").Group("rel_id").Find(&records)
for _, val := range records {
database.RedisTemplate.HSet(ctx, consts.REDIS_BLOG_VIEW_RECORD, map[string]any{val.RelId: val.Counts})
}
}
func (*articleService) GetBlogArticle(id string) blog.BlogArticle {
ctx := context.Background()
var article blog.BlogArticle
key := consts.REDIS_BLOG_ARTICLE + id
err := database.RedisTemplate.HGetAll(ctx, key).Scan(&article)
if err != nil || article.Id == "" {
database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article)
database.RedisTemplate.HSet(ctx, key, article)
}
return article
}
func (*articleService) GetAdminArticle(id string) admin.AdminArticle {
var article admin.AdminArticle
database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article)
return article
}
func (*articleService) PageAdminArticle(page int, itemsPerPage int) vo.Page[admin.AdminArticle] {
var content []admin.AdminArticle
var totalElements int64
database.GormTemplate.Table("blog_articles").Count(&totalElements)
database.GormTemplate.Table("blog_articles").
Where("del != ?", 1).
Offset((page - 1) * itemsPerPage).
Limit(itemsPerPage).
Order("create_time DESC").
Find(&content)
pre := int(totalElements) % itemsPerPage
if pre > 0 {
pre = 1
}
var totalPages int = int(totalElements)/itemsPerPage + pre
return vo.Page[admin.AdminArticle]{TotalElements: totalElements, TotalPages: totalPages, Number: page, Content: content}
}
func (*articleService) CreateArticle(articel *admin.AdminArticle) (string, error) {
time := time.Now().UnixMilli()
articleId := uuid.NewString()
articel.Id = articleId
articel.CreateTime = time
articel.UpdateTime = time
articel.Del = 0
articel.State = consts.ARTICLE_STATE_DRAFT
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error {
contentId := uuid.NewString()
content := articel.Content
commonContent := vo.CommonContent{Id: contentId, RelId: articleId, Content: content, State: "down"}
err := tx.Table("common_contents").Create(commonContent).Error
if err != nil {
return err
}
articel.Content = ""
err = tx.Table("blog_articles").Create(*articel).Error
return err
})
return articleId, err
}
func (*articleService) UpdateArticle(articel *admin.AdminArticle) (string, error) {
time := time.Now().UnixMilli()
articleId := articel.Id
articel.UpdateTime = time
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error {
//更新Article
tx.Table("blog_articles").Updates(articel)
//更新Content
err := tx.Table("common_contents").Where("rel_id", articleId).UpdateColumn("content", articel.Content).Error
return err
})
return articleId, err
}
func (*articleService) PublishArticle(id string) error {
now := time.Now().UnixMilli()
var article blog.BlogArticle
err := database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article).Error
if err != nil {
return err
}
if article.State != consts.ARTICLE_STATE_DRAFT {
return errors.New("发布失败,文章状态不是起草状态,无法发布")
}
article.PublishTime = now
article.State = consts.ARTICLE_STATE_PUBLISH
err = database.GormTemplate.Transaction(func(tx *gorm.DB) error {
var txErr error = tx.Table("blog_articles").Updates(&article).Error
if txErr != nil {
return errors.New("文章更新错误")
}
txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_PUBLISH)
if txErr != nil {
return errors.New("文本状态更新错误")
}
content, txErr := ContentService.GetContentByDb(id)
if txErr != nil {
return errors.New("文本查询错误")
}
ctx := context.Background()
txErr = database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
if txErr != nil {
return errors.New("缓存错误")
}
txErr = database.RedisTemplate.Set(ctx, consts.REDIS_BLOG_CONTENT+id, content.Content, time.Duration(0)).Err()
return txErr
})
return err
}
func (*articleService) UnPublishArticle(id string) error {
var article admin.AdminArticle
err := database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article).Error
if err != nil {
return err
}
if article.State != consts.CONTENT_STATE_PUBLISH {
return errors.New("撤下失败,文章状态不是已发布状态,无法撤下")
}
err = database.GormTemplate.Transaction(func(tx *gorm.DB) error {
var txErr error
ctx := context.Background()
txErr = database.RedisTemplate.ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST,
strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64),
strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64),
).Err()
// txErr = database.RedisTemplate.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
if txErr != nil {
return errors.New("缓存错误")
}
txErr = database.RedisTemplate.Del(ctx, consts.REDIS_BLOG_CONTENT+id).Err()
if txErr != nil {
return errors.New("缓存错误")
}
article.State = consts.ARTICLE_STATE_DRAFT
article.PublishTime = -1
txErr = tx.Table("blog_articles").Updates(&article).Error
if txErr != nil {
return errors.New("文章状态更新错误")
}
txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_DOWN)
return txErr
})
return err
}
func (*articleService) DelArticle(id string) error {
// articel := ArticleService.GetAdminArticle(id)
// err := database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article).Error
err := database.GormTemplate.Transaction(func(tx *gorm.DB) error {
txErr := tx.Table("blog_articles").Where("id = ?", id).UpdateColumn("del", 1).Error
return txErr
})
return err
}