Files
lv8girl/internal/controllers/home.go
nannanwu ddec422813 feat(core): 优化路径处理和配置端口并添加项目规范文档
- 将所有文件路径转换为 URL 友好格式,统一使用正斜杠,确保跨平台兼容
- 修改默认服务器监听端口为 :8989,提升默认配置适用性
- 数据库初始化时创建数据库文件夹,避免路径不存在导致错误
- 新增 AGENTS.md 文档,详细规范项目开发流程、代码风格、架构设计和安全性能指导
- 修正头像路径显示逻辑,确保头像 URL 正确展示
- 增加应用启动和开发的标准操作指南,提升团队协作效率
2026-02-24 20:44:05 +08:00

162 lines
4.1 KiB
Go

package controllers
import (
"net/http"
"path/filepath"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"lv8girl/internal/middleware"
"lv8girl/internal/repositories"
"lv8girl/internal/services"
)
type HomeController struct {
discussionSvc *services.DiscussionService
userSvc *services.UserService
messageSvc *services.MessageService
discussionRepo *repositories.DiscussionRepository
}
func NewHomeController() *HomeController {
return &HomeController{
discussionSvc: services.NewDiscussionService(),
userSvc: services.NewUserService(),
messageSvc: services.NewMessageService(),
discussionRepo: repositories.NewDiscussionRepository(),
}
}
func (c *HomeController) Index(ctx *gin.Context) {
session := sessions.Default(ctx)
userID, _ := session.Get("user_id").(uint)
username, _ := session.Get("username").(string)
userRole, _ := session.Get("user_role").(string)
isLoggedIn := userID != 0
if isLoggedIn {
userRepo := repositories.NewUserRepository()
userRepo.UpdateLastActive(userID)
}
posts, _ := c.discussionSvc.GetApprovedPosts(30)
// 处理头像路径,确保使用正斜杠并添加前导斜杠
for i := range posts {
if posts[i].Avatar != "" {
avatarPath := filepath.ToSlash(posts[i].Avatar)
posts[i].Avatar = "/" + avatarPath
}
}
var postCount, userCount, onlineCount int64
postCount, _ = c.discussionRepo.CountByStatus("approved")
userCount, onlineCount, _ = c.userSvc.GetUserStats()
var unreadCount int64
if isLoggedIn {
unreadCount, _ = c.messageSvc.GetUnreadCount(userID)
}
ctx.HTML(http.StatusOK, "index.html", gin.H{
"IsLoggedIn": isLoggedIn,
"UserID": userID,
"Username": username,
"UserRole": userRole,
"Posts": posts,
"PostCount": postCount,
"UserCount": userCount,
"OnlineCount": onlineCount,
"UnreadCount": unreadCount,
})
}
func (c *HomeController) ShowPost(ctx *gin.Context) {
postID := parseUint(ctx.Param("id"))
userID, username, userRole, isLoggedIn := middleware.GetCurrentUser(ctx)
session := sessions.Default(ctx)
viewedKey := "viewed_posts"
viewedPosts := session.Get(viewedKey)
var viewedMap map[uint]bool
if viewedPosts == nil {
viewedMap = make(map[uint]bool)
} else {
viewedMap = viewedPosts.(map[uint]bool)
}
if !viewedMap[postID] {
c.discussionSvc.IncrementViews(postID)
viewedMap[postID] = true
session.Set(viewedKey, viewedMap)
session.Save()
}
detail, err := c.discussionSvc.GetPostDetail(postID, userID)
if err != nil {
ctx.String(http.StatusNotFound, "帖子不存在")
return
}
comments, _ := c.discussionSvc.GetComments(postID)
avatar := ""
if detail.Post.User.Avatar != "" {
// 确保路径使用正斜杠,并添加前导斜杠
avatarPath := filepath.ToSlash(detail.Post.User.Avatar)
avatar = "/" + avatarPath
}
ctx.HTML(http.StatusOK, "post.html", gin.H{
"IsLoggedIn": isLoggedIn,
"UserID": userID,
"Username": username,
"UserRole": userRole,
"Post": detail.Post,
"PostAvatar": avatar,
"Comments": comments,
"LikeCount": detail.LikeCount,
"UserLiked": detail.UserLiked,
"AuthorPostCount": detail.AuthorPostCount,
})
}
func (c *HomeController) LikePost(ctx *gin.Context) {
userID, _, _, isLoggedIn := middleware.GetCurrentUser(ctx)
if !isLoggedIn {
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
return
}
postID := parseUint(ctx.Param("id"))
c.discussionSvc.AddLike(postID, userID)
ctx.Redirect(http.StatusFound, "/post/"+ctx.Param("id"))
}
func (c *HomeController) AddComment(ctx *gin.Context) {
userID, _, _, isLoggedIn := middleware.GetCurrentUser(ctx)
if !isLoggedIn {
ctx.Redirect(http.StatusFound, "/login")
return
}
postID := parseUint(ctx.Param("id"))
content := ctx.PostForm("content")
if content != "" {
c.discussionSvc.AddComment(postID, userID, content)
}
ctx.Redirect(http.StatusFound, "/post/"+ctx.Param("id"))
}
func parseUint(s string) uint {
var result uint
for _, c := range s {
if c >= '0' && c <= '9' {
result = result*10 + uint(c-'0')
}
}
return result
}