267 lines
8.2 KiB
Go
267 lines
8.2 KiB
Go
package service
|
|
|
|
import (
|
|
"Blog/internal/client"
|
|
"Blog/internal/consts"
|
|
"Blog/internal/model"
|
|
"Blog/internal/repository"
|
|
"context"
|
|
"errors"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/sirupsen/logrus"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var ArticleService *articleService = newArticleService()
|
|
|
|
type articleService struct {
|
|
}
|
|
|
|
func initArticleData() {
|
|
var slices []model.BlogArticle = repository.ArticleRepository.FindList(nil, "state = ?", consts.ARTICLE_STATE_PUBLISH)
|
|
logrus.Info("文章初始化数据加载量:", len(slices))
|
|
ctx := context.Background()
|
|
for _, article := range slices {
|
|
// logrus.Info(article)
|
|
publishTime := article.PublishTime
|
|
err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
|
|
if err != nil {
|
|
logrus.Info(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func newArticleService() *articleService {
|
|
go initArticleData()
|
|
|
|
return &articleService{}
|
|
}
|
|
|
|
// 根据ID获取文章
|
|
func (*articleService) GetArticle(id string) *model.BlogArticle {
|
|
var ret *model.BlogArticle = &model.BlogArticle{}
|
|
key := consts.REDIS_BLOG_ARTICLE + id
|
|
err := client.RedisClient.Get(context.Background(), key).Scan(ret)
|
|
if err != nil {
|
|
logrus.Infoln(id, "文章的缓存不存在,读取数据库")
|
|
ret = repository.ArticleRepository.GetById(id)
|
|
client.RedisClient.Set(context.Background(), key, ret, time.Duration(0))
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (*articleService) GetLatest() []model.BlogArticle {
|
|
ctx := context.Background()
|
|
var slices []model.BlogArticle
|
|
|
|
err := client.RedisClient.ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices)
|
|
// if err != nil || len(slices) == 0 {
|
|
// result := repository.ArticleRepository.Where("state = ?", consts.ARTICLE_STATE_PUBLISH).Order("publish_time DESC").Find(&slices)
|
|
// logrus.Info("文章初始化数据加载量:", result.RowsAffected)
|
|
// ctx := context.Background()
|
|
// client.RedisClient.Del(ctx, consts.REDIS_BLOG_ARTICLE_LATEST)
|
|
// for _, article := range slices {
|
|
// // logrus.Info(article)
|
|
// publishTime := article.PublishTime
|
|
// err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
|
|
// if err != nil {
|
|
// logrus.Info(err)
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
if err != nil {
|
|
logrus.Error("获取文章失败:", err)
|
|
return nil
|
|
}
|
|
return slices
|
|
}
|
|
|
|
// 文章分页
|
|
func (*articleService) PageArticle(page int, itemsPerPage int) model.Page[any] {
|
|
var slice []model.BlogArticle
|
|
var totalElements int64
|
|
ctx := context.Background()
|
|
repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Count(&totalElements)
|
|
repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).
|
|
Where("del != ?", 1).
|
|
Offset((page - 1) * itemsPerPage).
|
|
Limit(itemsPerPage).
|
|
Order("create_time DESC").
|
|
Find(&slice)
|
|
|
|
ret := []any{}
|
|
|
|
for _, v := range slice {
|
|
id := v.Id
|
|
view, _ := client.RedisClient.HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int64()
|
|
// content[i].View = view
|
|
var vo = struct {
|
|
model.BlogArticle
|
|
View int64 `json:"view"`
|
|
}{v, view}
|
|
|
|
ret = append(ret, vo)
|
|
}
|
|
|
|
pre := int(totalElements) % itemsPerPage
|
|
if pre > 0 {
|
|
pre = 1
|
|
}
|
|
var totalPages int = int(totalElements)/itemsPerPage + pre
|
|
|
|
return model.Page[any]{TotalElements: totalElements, TotalPages: totalPages, Number: page, Content: ret}
|
|
}
|
|
|
|
// 创建文章
|
|
func (*articleService) CreateArticle(articel *model.BlogArticle) (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 := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
|
|
contentId := uuid.NewString()
|
|
content := articel.Content
|
|
commonContent := model.BlogTextContent{Id: contentId, RelId: articleId, Content: content, State: consts.CONTENT_STATE_DOWN}
|
|
err := tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).Create(commonContent).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
articel.Content = ""
|
|
err = tx.Table(consts.TABLE_BLOG_ARTICLE).Create(*articel).Error
|
|
return err
|
|
})
|
|
|
|
return articleId, err
|
|
}
|
|
|
|
// 修改文章
|
|
func (*articleService) UpdateArticle(articel *model.BlogArticle) (string, error) {
|
|
time := time.Now().UnixMilli()
|
|
articleId := articel.Id
|
|
articel.UpdateTime = time
|
|
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
|
|
//更新Article
|
|
tx.Table(consts.TABLE_BLOG_ARTICLE).Updates(articel)
|
|
|
|
//更新Content
|
|
err := tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).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 model.BlogArticle
|
|
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
|
|
article := repository.ArticleRepository.GetById(id)
|
|
if article == nil {
|
|
return errors.New("不存在该文章")
|
|
}
|
|
|
|
if article.State != consts.ARTICLE_STATE_DRAFT {
|
|
return errors.New("发布失败,文章状态不是起草状态,无法发布")
|
|
}
|
|
|
|
if article.PublishTime == 0 {
|
|
article.PublishTime = now
|
|
}
|
|
article.State = consts.ARTICLE_STATE_PUBLISH
|
|
|
|
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
|
|
var txErr error = tx.Table(consts.TABLE_BLOG_ARTICLE).Updates(&article).Error
|
|
if txErr != nil {
|
|
return errors.New("文章更新错误")
|
|
}
|
|
// txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_PUBLISH)
|
|
txErr = tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).Where("rel_id = ?", id).UpdateColumn("state", consts.CONTENT_STATE_PUBLISH).Error
|
|
if txErr != nil {
|
|
return errors.New("文本状态更新错误")
|
|
}
|
|
content := TextContentService.GetContent(id)
|
|
if txErr != nil {
|
|
return errors.New("文本查询错误")
|
|
}
|
|
|
|
ctx := context.Background()
|
|
txErr = client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
|
|
if txErr != nil {
|
|
return errors.New("缓存错误")
|
|
}
|
|
txErr = client.RedisClient.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 model.BlogArticle
|
|
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
|
|
article := repository.ArticleRepository.GetById(id)
|
|
if article == nil {
|
|
return errors.New("不存在该文章")
|
|
}
|
|
|
|
if article.State != consts.CONTENT_STATE_PUBLISH {
|
|
return errors.New("撤下失败,文章状态不是已发布状态,无法撤下")
|
|
}
|
|
|
|
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
|
|
var txErr error
|
|
ctx := context.Background()
|
|
txErr = client.RedisClient.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 = client.RedisClient.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
|
|
if txErr != nil {
|
|
return errors.New("缓存错误")
|
|
}
|
|
|
|
txErr = client.RedisClient.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(consts.TABLE_BLOG_ARTICLE).Updates(&article).Error
|
|
if txErr != nil {
|
|
return errors.New("文章状态更新错误")
|
|
}
|
|
// txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_DOWN)
|
|
txErr = tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).Where("rel_id = ?", id).UpdateColumn("state", consts.CONTENT_STATE_DOWN).Error
|
|
|
|
return txErr
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
// 删除文章
|
|
func (*articleService) DelArticle(id string) error {
|
|
// articel := ArticleService.GetAdminArticle(id)
|
|
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
|
|
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
|
|
txErr := tx.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).UpdateColumn("del", 1).Error
|
|
return txErr
|
|
})
|
|
|
|
return err
|
|
}
|