20251209
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bbs-go/internal/models/constants"
|
||||
"bbs-go/internal/pkg/bbsurls"
|
||||
"bbs-go/internal/pkg/errs"
|
||||
"bbs-go/internal/spam"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/mlogclub/simple/common/jsons"
|
||||
"github.com/mlogclub/simple/sqls"
|
||||
"github.com/mlogclub/simple/web"
|
||||
"github.com/mlogclub/simple/web/params"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"bbs-go/internal/controllers/render"
|
||||
"bbs-go/internal/models"
|
||||
"bbs-go/internal/services"
|
||||
)
|
||||
|
||||
type ArticleController struct {
|
||||
Ctx iris.Context
|
||||
}
|
||||
|
||||
func (c *ArticleController) GetClean() *web.JsonResult {
|
||||
go func() {
|
||||
p, _ := ants.NewPool(10)
|
||||
services.ArticleService.ScanDesc(func(articles []models.Article) {
|
||||
var ids []int64
|
||||
for _, article := range articles {
|
||||
if article.ContentType == constants.ContentTypeHtml {
|
||||
ids = append(ids, article.Id)
|
||||
}
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
p.Submit(func() {
|
||||
sqls.DB().Delete(&models.Article{}, "id in ?", ids)
|
||||
logrus.Info("清理文章:", ids)
|
||||
})
|
||||
}
|
||||
})
|
||||
}()
|
||||
return web.JsonSuccess()
|
||||
}
|
||||
|
||||
// 文章详情
|
||||
func (c *ArticleController) GetBy(articleId int64) *web.JsonResult {
|
||||
article := services.ArticleService.Get(articleId)
|
||||
if article == nil || article.Status == constants.StatusDeleted {
|
||||
return web.JsonErrorCode(404, "文章不存在")
|
||||
}
|
||||
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
|
||||
// 审核中文章控制展示
|
||||
if article.Status == constants.StatusReview {
|
||||
if user != nil {
|
||||
if article.UserId != user.Id && !user.IsOwnerOrAdmin() {
|
||||
return web.JsonErrorCode(403, "文章审核中")
|
||||
}
|
||||
} else {
|
||||
return web.JsonErrorCode(403, "文章审核中")
|
||||
}
|
||||
}
|
||||
|
||||
services.ArticleService.IncrViewCount(articleId) // 增加浏览量
|
||||
return web.JsonData(render.BuildArticle(article, user))
|
||||
}
|
||||
|
||||
// PostCreate 发表文章
|
||||
func (c *ArticleController) PostCreate() *web.JsonResult {
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
if err := services.UserService.CheckPostStatus(user); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
form := models.GetCreateArticleForm(c.Ctx)
|
||||
|
||||
if err := spam.CheckArticle(user, form); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
|
||||
article, err := services.ArticleService.Publish(user.Id, form)
|
||||
if err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
return web.JsonData(render.BuildArticle(article, user))
|
||||
}
|
||||
|
||||
// 编辑时获取详情
|
||||
func (c *ArticleController) GetEditBy(articleId int64) *web.JsonResult {
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
if err := services.UserService.CheckPostStatus(user); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
|
||||
article := services.ArticleService.Get(articleId)
|
||||
if article == nil || article.Status == constants.StatusDeleted {
|
||||
return web.JsonErrorMsg("话题不存在或已被删除")
|
||||
}
|
||||
|
||||
// 非作者、且非管理员
|
||||
if article.UserId != user.Id && !user.HasAnyRole(constants.RoleAdmin, constants.RoleOwner) {
|
||||
return web.JsonErrorMsg("无权限")
|
||||
}
|
||||
|
||||
tags := services.ArticleService.GetArticleTags(articleId)
|
||||
var tagNames []string
|
||||
if len(tags) > 0 {
|
||||
for _, tag := range tags {
|
||||
tagNames = append(tagNames, tag.Name)
|
||||
}
|
||||
}
|
||||
|
||||
var cover *models.ImageDTO
|
||||
if err := jsons.Parse(article.Cover, &cover); err != nil {
|
||||
slog.Error(err.Error(), slog.Any("err", err))
|
||||
}
|
||||
|
||||
return web.NewEmptyRspBuilder().
|
||||
Put("id", article.Id).
|
||||
Put("articleId", article.Id).
|
||||
Put("title", article.Title).
|
||||
Put("content", article.Content).
|
||||
Put("tags", tagNames).
|
||||
Put("cover", cover).
|
||||
JsonResult()
|
||||
}
|
||||
|
||||
// 编辑文章
|
||||
func (c *ArticleController) PostEditBy(articleId int64) *web.JsonResult {
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
if err := services.UserService.CheckPostStatus(user); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
|
||||
var (
|
||||
tags = params.FormValueStringArray(c.Ctx, "tags")
|
||||
title = c.Ctx.PostValue("title")
|
||||
content = c.Ctx.PostValue("content")
|
||||
cover = models.GetImageDTO(c.Ctx, "cover")
|
||||
)
|
||||
|
||||
article := services.ArticleService.Get(articleId)
|
||||
if article == nil || article.Status == constants.StatusDeleted {
|
||||
return web.JsonErrorMsg("文章不存在")
|
||||
}
|
||||
|
||||
// 非作者、且非管理员
|
||||
if article.UserId != user.Id && !user.HasAnyRole(constants.RoleAdmin, constants.RoleOwner) {
|
||||
return web.JsonErrorMsg("无权限")
|
||||
}
|
||||
|
||||
if err := services.ArticleService.Edit(articleId, tags, title, content, cover); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
// 操作日志
|
||||
services.OperateLogService.AddOperateLog(user.Id, constants.OpTypeUpdate, constants.EntityArticle, articleId,
|
||||
"", c.Ctx.Request())
|
||||
return web.NewEmptyRspBuilder().Put("articleId", article.Id).JsonResult()
|
||||
}
|
||||
|
||||
// 删除文章
|
||||
func (c *ArticleController) PostDeleteBy(articleId int64) *web.JsonResult {
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
if err := services.UserService.CheckPostStatus(user); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
|
||||
article := services.ArticleService.Get(articleId)
|
||||
if article == nil || article.Status == constants.StatusDeleted {
|
||||
return web.JsonErrorMsg("文章不存在")
|
||||
}
|
||||
|
||||
// 非作者、且非管理员
|
||||
if article.UserId != user.Id && !user.HasAnyRole(constants.RoleAdmin, constants.RoleOwner) {
|
||||
return web.JsonErrorMsg("无权限")
|
||||
}
|
||||
|
||||
if err := services.ArticleService.Delete(articleId); err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
// 操作日志
|
||||
services.OperateLogService.AddOperateLog(user.Id, constants.OpTypeDelete, constants.EntityArticle, articleId,
|
||||
"", c.Ctx.Request())
|
||||
return web.JsonSuccess()
|
||||
}
|
||||
|
||||
// 收藏文章
|
||||
func (c *ArticleController) PostFavoriteBy(articleId int64) *web.JsonResult {
|
||||
user := services.UserTokenService.GetCurrent(c.Ctx)
|
||||
if user == nil {
|
||||
return web.JsonError(errs.NotLogin)
|
||||
}
|
||||
err := services.FavoriteService.AddArticleFavorite(user.Id, articleId)
|
||||
if err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
return web.JsonSuccess()
|
||||
}
|
||||
|
||||
// 文章跳转链接
|
||||
func (c *ArticleController) GetRedirectBy(articleId int64) *web.JsonResult {
|
||||
article := services.ArticleService.Get(articleId)
|
||||
if article == nil || article.Status != constants.StatusOk {
|
||||
return web.JsonErrorMsg("文章不存在")
|
||||
}
|
||||
return web.NewEmptyRspBuilder().Put("url", bbsurls.ArticleUrl(articleId)).JsonResult()
|
||||
}
|
||||
|
||||
// 用户文章列表
|
||||
func (c *ArticleController) GetUserArticles() *web.JsonResult {
|
||||
userId, err := params.FormValueInt64(c.Ctx, "userId")
|
||||
if err != nil {
|
||||
return web.JsonError(err)
|
||||
}
|
||||
cursor := params.FormValueInt64Default(c.Ctx, "cursor", 0)
|
||||
articles, cursor, hasMore := services.ArticleService.GetUserArticles(userId, cursor)
|
||||
return web.JsonCursorData(render.BuildSimpleArticles(articles), strconv.FormatInt(cursor, 10), hasMore)
|
||||
}
|
||||
|
||||
// 文章列表
|
||||
func (c *ArticleController) GetArticles() *web.JsonResult {
|
||||
cursor := params.FormValueInt64Default(c.Ctx, "cursor", 0)
|
||||
articles, cursor, hasMore := services.ArticleService.GetArticles(cursor)
|
||||
return web.JsonCursorData(render.BuildSimpleArticles(articles), strconv.FormatInt(cursor, 10), hasMore)
|
||||
}
|
||||
|
||||
// 标签文章列表
|
||||
func (c *ArticleController) GetTagArticles() *web.JsonResult {
|
||||
cursor := params.FormValueInt64Default(c.Ctx, "cursor", 0)
|
||||
tagId := params.FormValueInt64Default(c.Ctx, "tagId", 0)
|
||||
articles, cursor, hasMore := services.ArticleService.GetTagArticles(tagId, cursor)
|
||||
return web.JsonCursorData(render.BuildSimpleArticles(articles), strconv.FormatInt(cursor, 10), hasMore)
|
||||
}
|
||||
Reference in New Issue
Block a user