125 lines
3.3 KiB
Go
125 lines
3.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"metazone.cc/mce/internal/common"
|
|
"metazone.cc/mce/internal/model"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ListPage 帖子列表页
|
|
func (ctrl *PostController) ListPage(c *gin.Context) {
|
|
keyword := c.Query("keyword")
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
|
|
|
posts, total, err := ctrl.postService.List(keyword, page, pageSize)
|
|
if err != nil {
|
|
c.HTML(http.StatusOK, "posts/index.html", common.BuildPageData(c, gin.H{
|
|
"Title": "社区帖子",
|
|
"Error": "加载帖子列表失败",
|
|
}))
|
|
return
|
|
}
|
|
|
|
totalPages := common.PageCount(total, pageSize)
|
|
prevPage := page - 1
|
|
if prevPage < 1 {
|
|
prevPage = 1
|
|
}
|
|
nextPage := page + 1
|
|
if nextPage > totalPages {
|
|
nextPage = totalPages
|
|
}
|
|
|
|
c.HTML(http.StatusOK, "posts/index.html", common.BuildPageData(c, gin.H{
|
|
"Title": "社区帖子",
|
|
"Posts": posts,
|
|
"Total": total,
|
|
"Page": page,
|
|
"TotalPages": totalPages,
|
|
"PrevPage": prevPage,
|
|
"NextPage": nextPage,
|
|
"Keyword": keyword,
|
|
"ExtraCSS": "/static/css/posts.css",
|
|
}))
|
|
}
|
|
|
|
// ShowPage 帖子详情页
|
|
func (ctrl *PostController) ShowPage(c *gin.Context) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
c.HTML(http.StatusNotFound, "posts/404.html", common.BuildPageData(c, gin.H{
|
|
"Title": "未找到",
|
|
"ExtraCSS": "/static/css/posts.css",
|
|
}))
|
|
return
|
|
}
|
|
|
|
post, err := ctrl.postService.GetByID(uint(id))
|
|
if err != nil {
|
|
c.HTML(http.StatusNotFound, "posts/404.html", common.BuildPageData(c, gin.H{
|
|
"Title": "未找到",
|
|
"ExtraCSS": "/static/css/posts.css",
|
|
}))
|
|
return
|
|
}
|
|
|
|
uid, role, _ := common.GetGinUser(c)
|
|
|
|
// 仅 approved 公开可见(作者本人 + moderator+ 可预览其他状态)
|
|
if post.Status != model.PostStatusApproved && !ctrl.postService.IsPostAccessible(uid, role, post.UserID) {
|
|
// 未登录用户:引导登录后回到当前帖子
|
|
if uid == 0 {
|
|
common.RedirectToLogin(c)
|
|
return
|
|
}
|
|
c.HTML(http.StatusNotFound, "posts/404.html", common.BuildPageData(c, gin.H{
|
|
"Title": "未找到",
|
|
"ExtraCSS": "/static/css/posts.css",
|
|
}))
|
|
return
|
|
}
|
|
|
|
// 已登录用户阅读计数(已发布帖子,自动去重+防刷)
|
|
if uid > 0 && post.Status == model.PostStatusApproved {
|
|
ctrl.postService.RecordRead(uid, post.ID)
|
|
}
|
|
|
|
// 访客阅读计数(基于 Cookie 标识去重+防刷)
|
|
if uid == 0 && post.Status == model.PostStatusApproved {
|
|
vid := ctrl.getVisitorID(c)
|
|
ctrl.postService.RecordGuestRead(vid, post.ID)
|
|
}
|
|
|
|
ctrl.applyShortcode(post)
|
|
|
|
// Open Graph 社交分享数据
|
|
ogImage := common.ExtractFirstImage(post.Body)
|
|
if ogImage != "" && !strings.HasPrefix(ogImage, "http") {
|
|
prefix := ""
|
|
if !strings.HasPrefix(ogImage, "/") {
|
|
prefix = "/"
|
|
}
|
|
ogImage = "https://" + c.Request.Host + prefix + ogImage
|
|
}
|
|
ogURL := fmt.Sprintf("https://%s/posts/%d", c.Request.Host, id)
|
|
|
|
c.HTML(http.StatusOK, "posts/show.html", common.BuildPageData(c, gin.H{
|
|
"Title": post.Title,
|
|
"Post": post,
|
|
"UID": uid,
|
|
"StatusNames": common.PostStatusDisplayNames,
|
|
"ExtraCSS": "/static/css/posts.css",
|
|
"OgTitle": post.Title,
|
|
"OgDescription": post.Excerpt,
|
|
"OgImage": ogImage,
|
|
"OgURL": ogURL,
|
|
}))
|
|
}
|