You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sonic/service/impl/sheet.go

251 lines
7.2 KiB
Go

package impl
import (
"context"
"net/url"
"strconv"
"strings"
"time"
"github.com/go-sonic/sonic/cache"
"github.com/go-sonic/sonic/consts"
"github.com/go-sonic/sonic/dal"
"github.com/go-sonic/sonic/event"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/entity"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util"
)
type sheetServiceImpl struct {
service.BasePostService
MetaService service.MetaService
OptionService service.OptionService
SheetCommentService service.SheetCommentService
Event event.Bus
Cache cache.Cache
ThemeService service.ThemeService
}
func NewSheetService(basePostService service.BasePostService,
metaService service.MetaService,
optionService service.OptionService,
sheetCommentService service.SheetCommentService,
event event.Bus,
cache cache.Cache,
themeService service.ThemeService,
) service.SheetService {
return &sheetServiceImpl{
BasePostService: basePostService,
MetaService: metaService,
OptionService: optionService,
SheetCommentService: sheetCommentService,
Event: event,
Cache: cache,
ThemeService: themeService,
}
}
func (s sheetServiceImpl) Page(ctx context.Context, page param.Page, sort *param.Sort) ([]*entity.Post, int64, error) {
sheetDAL := dal.GetQueryByCtx(ctx).Post
sheetDO := sheetDAL.WithContext(ctx).Where(sheetDAL.Type.Eq(consts.PostTypeSheet))
err := BuildSort(sort, &sheetDAL, &sheetDO)
if err != nil {
return nil, 0, err
}
sheets, totalCount, err := sheetDO.FindByPage(page.PageSize*page.PageNum, page.PageSize)
if err != nil {
return nil, 0, err
}
return sheets, totalCount, nil
}
func (s sheetServiceImpl) Create(ctx context.Context, sheetParam *param.Sheet) (*entity.Post, error) {
sheet, err := s.ConvertParam(ctx, sheetParam)
if err != nil {
return nil, err
}
sheet, err = s.CreateOrUpdate(ctx, sheet, nil, nil, sheetParam.Metas)
if err != nil {
return nil, err
}
return sheet, nil
}
func (s sheetServiceImpl) ConvertParam(ctx context.Context, sheetParam *param.Sheet) (*entity.Post, error) {
sheet := &entity.Post{
Type: consts.PostTypeSheet,
DisallowComment: sheetParam.DisallowComment,
OriginalContent: sheetParam.OriginalContent,
FormatContent: sheetParam.Content,
Password: sheetParam.Password,
MetaDescription: sheetParam.MetaDescription,
MetaKeywords: sheetParam.MetaKeywords,
Template: sheetParam.Template,
Thumbnail: sheetParam.Thumbnail,
Title: sheetParam.Title,
TopPriority: sheetParam.TopPriority,
Status: sheetParam.Status,
Summary: sheetParam.Summary,
EditTime: util.TimePtr(time.Now()),
}
if sheetParam.EditorType != nil {
sheet.EditorType = *sheetParam.EditorType
} else {
sheet.EditorType = consts.EditorTypeMarkdown
}
sheet.WordCount = util.HtmlFormatWordCount(sheet.FormatContent)
if sheetParam.Slug == "" {
sheet.Slug = util.Slug(sheetParam.Title)
} else {
sheet.Slug = util.Slug(sheetParam.Slug)
}
if sheetParam.CreateTime != nil {
sheet.CreateTime = time.Unix(*sheetParam.CreateTime, 0)
}
return sheet, nil
}
func (s sheetServiceImpl) Update(ctx context.Context, sheetID int32, sheetParam *param.Sheet) (*entity.Post, error) {
sheetDAL := dal.GetQueryByCtx(ctx).Post
sheet, err := sheetDAL.WithContext(ctx).Where(sheetDAL.ID.Eq(sheetID)).First()
if err != nil {
return nil, WrapDBErr(err)
}
sheetToUpdate, err := s.ConvertParam(ctx, sheetParam)
if err != nil {
return nil, err
}
sheetToUpdate.ID = sheet.ID
sheetToUpdate.Type = sheet.Type
if sheetToUpdate.CreateTime == (time.Time{}) {
sheetToUpdate.CreateTime = sheet.CreateTime
}
sheetToUpdate.CreateTime = sheet.CreateTime
sheetToUpdate.Likes = sheet.Likes
sheetToUpdate.Visits = sheet.Visits
sheet, err = s.CreateOrUpdate(ctx, sheetToUpdate, nil, nil, sheetParam.Metas)
if err != nil {
return nil, err
}
s.Event.Publish(ctx, &event.LogEvent{
LogKey: strconv.Itoa(int(sheet.ID)),
LogType: consts.LogTypeSheetEdited,
Content: sheet.Title,
IpAddress: util.GetClientIP(ctx),
})
return sheet, nil
}
func (s sheetServiceImpl) Preview(ctx context.Context, sheetID int32) (string, error) {
post, err := s.GetByPostID(ctx, sheetID)
if err != nil {
return "", err
}
token := util.GenUUIDWithOutDash()
s.Cache.Set(token, token, time.Minute*10)
previewURL := strings.Builder{}
isEnabledAbsolutePath, err := s.OptionService.IsEnabledAbsolutePath(ctx)
if err != nil {
return "", err
}
if isEnabledAbsolutePath {
blogBaseURL, err := s.OptionService.GetBlogBaseURL(ctx)
if err != nil {
return "", err
}
previewURL.WriteString(blogBaseURL)
}
post.Slug = url.QueryEscape(post.Slug)
fullPath, err := s.BuildFullPath(ctx, post)
if err != nil {
return "", err
}
previewURL.WriteString("/")
previewURL.WriteString(fullPath)
previewURL.WriteString("?token=")
previewURL.WriteString(token)
return previewURL.String(), nil
}
func (s sheetServiceImpl) CountVisit(ctx context.Context) (int64, error) {
var count float64
sheetDAL := dal.GetQueryByCtx(ctx).Post
err := sheetDAL.WithContext(ctx).Select(sheetDAL.Visits.Sum().IfNull(0)).Where(sheetDAL.Type.Eq(consts.PostTypeSheet), sheetDAL.Status.Eq(consts.PostStatusPublished)).Scan(&count)
if err != nil {
return 0, WrapDBErr(err)
}
return int64(count), nil
}
func (s sheetServiceImpl) CountLike(ctx context.Context) (int64, error) {
var count float64
sheetDAL := dal.GetQueryByCtx(ctx).Post
err := sheetDAL.WithContext(ctx).Select(sheetDAL.Likes.Sum().IfNull(0)).Where(sheetDAL.Type.Eq(consts.PostTypeSheet), sheetDAL.Status.Eq(consts.PostStatusPublished)).Scan(&count)
if err != nil {
return 0, WrapDBErr(err)
}
return int64(count), nil
}
func (s sheetServiceImpl) ListIndependentSheets(ctx context.Context) ([]*dto.IndependentSheet, error) {
isEnableAbsolutePath, err := s.OptionService.IsEnabledAbsolutePath(ctx)
if err != nil {
return nil, err
}
var sheetBaseURL string
if isEnableAbsolutePath {
sheetBaseURL, err = s.OptionService.GetBlogBaseURL(ctx)
if err != nil {
return nil, err
}
sheetBaseURL += "/"
} else {
sheetBaseURL = "/"
}
linkPrefix, err := s.OptionService.GetLinksPrefix(ctx)
if err != nil {
return nil, err
}
linkSheet := dto.IndependentSheet{
ID: 1,
Title: "友情链接",
FullPath: sheetBaseURL + linkPrefix,
RouteName: "LinkList",
Available: true,
}
linkSheet.Available, _ = s.ThemeService.TemplateExist(ctx, "links.tmpl")
photoPrefix, err := s.OptionService.GetPhotoPrefix(ctx)
if err != nil {
return nil, err
}
photoSheet := dto.IndependentSheet{
ID: 2,
Title: "图库页面",
FullPath: sheetBaseURL + photoPrefix,
RouteName: "PhotoList",
Available: true,
}
photoSheet.Available, _ = s.ThemeService.TemplateExist(ctx, "photos.tmpl")
journalPrefix, err := s.OptionService.GetJournalPrefix(ctx)
if err != nil {
return nil, err
}
journalSheet := dto.IndependentSheet{
ID: 3,
Title: "日志页面",
FullPath: sheetBaseURL + journalPrefix,
RouteName: "JournalList",
Available: true,
}
journalSheet.Available, _ = s.ThemeService.TemplateExist(ctx, "journals.tmpl")
return []*dto.IndependentSheet{&linkSheet, &photoSheet, &journalSheet}, nil
}