fix: 完成 Gitea 目录改组收尾(import、构建与 LICENSE)
同步包路径与路由,去掉 SPA 构建步骤,对齐 Gitea 式 LICENSE,并更新规格/规则与占位 SSR。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package handler
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
@@ -10,58 +10,58 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"git.iioio.com/freefire/jiang13-forum/config"
|
||||
"git.iioio.com/freefire/jiang13-forum/middleware"
|
||||
"git.iioio.com/freefire/jiang13-forum/model"
|
||||
"git.iioio.com/freefire/jiang13-forum/service"
|
||||
"git.iioio.com/freefire/jiang13-forum/modules/auth"
|
||||
"git.iioio.com/freefire/jiang13-forum/models"
|
||||
"git.iioio.com/freefire/jiang13-forum/services"
|
||||
)
|
||||
|
||||
// Handlers 聚合所有 HTTP 处理器
|
||||
type Handlers struct {
|
||||
Cfg *config.Config
|
||||
Store *service.UploadStore
|
||||
Auth *service.AuthService
|
||||
User *service.UserService
|
||||
Board *service.BoardService
|
||||
Post *service.PostService
|
||||
Comment *service.CommentService
|
||||
Message *service.MessageService
|
||||
Notify *service.NotifyService
|
||||
Report *service.ReportService
|
||||
Backup *service.BackupService
|
||||
Filter *service.SensitiveFilter
|
||||
Limiter *service.RateLimiter
|
||||
Settings *service.ForumSettingsService
|
||||
Captcha *service.CaptchaService
|
||||
Mail *service.MailService
|
||||
EmailCode *service.EmailCodeService
|
||||
OIDC *service.OIDCService
|
||||
Gitea *service.GiteaService
|
||||
Points *service.PointsService
|
||||
Badge *service.BadgeService
|
||||
SitePage *service.SitePageService
|
||||
FriendLinkApply *service.FriendLinkApplyService
|
||||
Store *services.UploadStore
|
||||
Auth *services.AuthService
|
||||
User *services.UserService
|
||||
Board *services.BoardService
|
||||
Post *services.PostService
|
||||
Comment *services.CommentService
|
||||
Message *services.MessageService
|
||||
Notify *services.NotifyService
|
||||
Report *services.ReportService
|
||||
Backup *services.BackupService
|
||||
Filter *services.SensitiveFilter
|
||||
Limiter *services.RateLimiter
|
||||
Settings *services.ForumSettingsService
|
||||
Captcha *services.CaptchaService
|
||||
Mail *services.MailService
|
||||
EmailCode *services.EmailCodeService
|
||||
OIDC *services.OIDCService
|
||||
Gitea *services.GiteaService
|
||||
Points *services.PointsService
|
||||
Badge *services.BadgeService
|
||||
SitePage *services.SitePageService
|
||||
FriendLinkApply *services.FriendLinkApplyService
|
||||
}
|
||||
|
||||
func (h *Handlers) setAuthCookie(c *gin.Context, token string) {
|
||||
c.SetCookie(middleware.CookieName, token, int(service.TokenExpire.Seconds()), "/", "", false, true)
|
||||
c.SetCookie(auth.CookieName, token, int(services.TokenExpire.Seconds()), "/", "", false, true)
|
||||
}
|
||||
|
||||
func (h *Handlers) currentUserID(c *gin.Context) uint {
|
||||
if v, ok := c.Get(middleware.CtxUserID); ok {
|
||||
if v, ok := c.Get(auth.CtxUserID); ok {
|
||||
return v.(uint)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (h *Handlers) isAdmin(c *gin.Context) bool {
|
||||
if v, ok := c.Get(middleware.CtxRole); ok {
|
||||
return v == model.RoleAdmin
|
||||
if v, ok := c.Get(auth.CtxRole); ok {
|
||||
return v == models.RoleAdmin
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// loadCurrentUser 加载当前登录用户完整资料(含认证/积分)
|
||||
func (h *Handlers) loadCurrentUser(c *gin.Context) (*model.User, error) {
|
||||
func (h *Handlers) loadCurrentUser(c *gin.Context) (*models.User, error) {
|
||||
uid := h.currentUserID(c)
|
||||
if uid == 0 {
|
||||
return nil, errors.New("未登录")
|
||||
@@ -133,7 +133,7 @@ func (h *Handlers) APIRegisterConfig(c *gin.Context) {
|
||||
"mail_ready": mailReady,
|
||||
"require_email_code": mailReady,
|
||||
"register_open": userCount == 0 || mailReady,
|
||||
"email_code_len": service.EmailCodeLen,
|
||||
"email_code_len": services.EmailCodeLen,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ func (h *Handlers) APISendRegisterEmailCode(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if !h.Settings.MailReady() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrMailNotConfigured.Error()})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrMailNotConfigured.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.EmailCode.SendRegisterCode(req.Email); err != nil {
|
||||
@@ -167,7 +167,7 @@ func (h *Handlers) APISendResetEmailCode(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if !h.Settings.MailReady() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrMailNotConfigured.Error()})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrMailNotConfigured.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.EmailCode.SendResetCode(req.Email); err != nil {
|
||||
@@ -189,11 +189,11 @@ func (h *Handlers) APIResetPassword(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if !h.Settings.MailReady() {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrMailNotConfigured.Error()})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrMailNotConfigured.Error()})
|
||||
return
|
||||
}
|
||||
if !h.EmailCode.VerifyPurpose(service.EmailCodePurposeReset, req.Email, req.EmailCode) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrEmailCodeInvalid.Error()})
|
||||
if !h.EmailCode.VerifyPurpose(services.EmailCodePurposeReset, req.Email, req.EmailCode) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrEmailCodeInvalid.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.User.ResetPasswordByEmail(req.Email, req.NewPassword); err != nil {
|
||||
@@ -244,12 +244,12 @@ func (h *Handlers) APIRegister(c *gin.Context) {
|
||||
userCount := h.Auth.UserCount()
|
||||
mailReady := h.Settings.MailReady()
|
||||
if userCount > 0 && !mailReady {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrRegisterClosed.Error()})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrRegisterClosed.Error()})
|
||||
return
|
||||
}
|
||||
if mailReady {
|
||||
if !h.EmailCode.Verify(req.Email, req.EmailCode) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": service.ErrEmailCodeInvalid.Error()})
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": services.ErrEmailCodeInvalid.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func (h *Handlers) APILogin(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Handlers) APILogout(c *gin.Context) {
|
||||
c.SetCookie(middleware.CookieName, "", -1, "/", "", false, true)
|
||||
c.SetCookie(auth.CookieName, "", -1, "/", "", false, true)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "已退出"})
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ func (h *Handlers) APIUserPublic(c *gin.Context) {
|
||||
if h.Badge != nil {
|
||||
_ = h.Badge.EvaluateAuto(user.ID)
|
||||
if badges, bErr := h.Badge.ListUserBadges(user.ID); bErr == nil {
|
||||
view.Badges = service.BadgeViews(badges, 0)
|
||||
view.Badges = services.BadgeViews(badges, 0)
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
@@ -396,10 +396,10 @@ func (h *Handlers) APIUploadPostImage(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
uid := h.currentUserID(c)
|
||||
url, err := service.SaveUploadedImage(
|
||||
url, err := services.SaveUploadedImage(
|
||||
h.Store,
|
||||
file,
|
||||
service.UploadCategoryPosts,
|
||||
services.UploadCategoryPosts,
|
||||
fmt.Sprintf("%d", uid),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -421,20 +421,20 @@ func (h *Handlers) APICreatePost(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
extras := service.ParsePostExtrasFromForm(
|
||||
extras := services.ParsePostExtrasFromForm(
|
||||
c.PostForm("poll_options"),
|
||||
c.PostForm("bounty_points"),
|
||||
c.PostForm("lottery_winner_count"),
|
||||
)
|
||||
if post.PostType == model.PostTypePoll || post.PostType == model.PostTypeBounty || post.PostType == model.PostTypeLottery {
|
||||
if err := service.FinalizeSpecialPostCreate(post, h.currentUserID(c), extras); err != nil {
|
||||
if post.PostType == models.PostTypePoll || post.PostType == models.PostTypeBounty || post.PostType == models.PostTypeLottery {
|
||||
if err := services.FinalizeSpecialPostCreate(post, h.currentUserID(c), extras); err != nil {
|
||||
_ = h.Post.Delete(h.currentUserID(c), post.ID, true)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
msg := "发帖成功"
|
||||
if post.Status == model.ContentStatusPending {
|
||||
if post.Status == models.ContentStatusPending {
|
||||
msg = "已提交审核,通过后将公开显示"
|
||||
if h.Notify != nil {
|
||||
h.Notify.AsyncNotifyPendingPost(post)
|
||||
@@ -479,8 +479,8 @@ func (h *Handlers) APIToggleLike(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
var post model.Post
|
||||
model.DB.First(&post, id)
|
||||
var post models.Post
|
||||
models.DB.First(&post, id)
|
||||
c.JSON(http.StatusOK, gin.H{"liked": liked, "like_count": post.LikeCount})
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ func (h *Handlers) APICreateComment(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
in := service.CommentCreateInput{
|
||||
in := services.CommentCreateInput{
|
||||
UserID: uid,
|
||||
PostID: uint(postID),
|
||||
Content: content,
|
||||
@@ -551,14 +551,14 @@ func (h *Handlers) APICreateComment(c *gin.Context) {
|
||||
msg := "评论成功"
|
||||
if h.Notify != nil {
|
||||
switch comment.Status {
|
||||
case model.ContentStatusPublished:
|
||||
case models.ContentStatusPublished:
|
||||
h.Notify.AsyncNotifyCommentPublished(comment)
|
||||
h.Notify.AsyncNotifyCommentMentions(comment)
|
||||
case model.ContentStatusPending:
|
||||
case models.ContentStatusPending:
|
||||
msg = "评论已提交,审核通过后公开显示"
|
||||
h.Notify.AsyncNotifyPendingComment(comment)
|
||||
}
|
||||
} else if comment.Status == model.ContentStatusPending {
|
||||
} else if comment.Status == models.ContentStatusPending {
|
||||
msg = "评论已提交,审核通过后公开显示"
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": msg, "floor": comment.Floor, "id": comment.ID, "status": comment.Status})
|
||||
@@ -586,7 +586,7 @@ func (h *Handlers) APIUpdateComment(c *gin.Context) {
|
||||
status := ""
|
||||
if comment, e := h.Comment.GetByID(uint(id)); e == nil {
|
||||
status = comment.Status
|
||||
if status == model.ContentStatusPending && !h.isAdmin(c) {
|
||||
if status == models.ContentStatusPending && !h.isAdmin(c) {
|
||||
msg = "评论已更新,审核通过后公开显示"
|
||||
}
|
||||
if enteredPending && h.Notify != nil {
|
||||
|
||||
Reference in New Issue
Block a user