fix: 完成 Gitea 目录改组收尾(import、构建与 LICENSE)

同步包路径与路由,去掉 SPA 构建步骤,对齐 Gitea 式 LICENSE,并更新规格/规则与占位 SSR。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-29 04:01:20 +08:00
parent 9fe299a45f
commit 3f50316ad0
93 changed files with 1472 additions and 1522 deletions

View File

@@ -1,11 +1,11 @@
package service
package services
import (
"errors"
"testing"
"github.com/glebarez/sqlite"
"git.iioio.com/freefire/jiang13-forum/model"
"git.iioio.com/freefire/jiang13-forum/models"
"gorm.io/gorm"
)
@@ -15,26 +15,26 @@ func setupBountyTestDB(t *testing.T) *gorm.DB {
if err != nil {
t.Fatal(err)
}
if err := db.AutoMigrate(&model.User{}, &model.Post{}, &model.Comment{}, &model.PointLedger{}); err != nil {
if err := db.AutoMigrate(&models.User{}, &models.Post{}, &models.Comment{}, &models.PointLedger{}); err != nil {
t.Fatal(err)
}
prev := model.DB
model.DB = db
t.Cleanup(func() { model.DB = prev })
prev := models.DB
models.DB = db
t.Cleanup(func() { models.DB = prev })
return db
}
func seedBountyPost(t *testing.T, db *gorm.DB, authorID uint, points int) model.Post {
func seedBountyPost(t *testing.T, db *gorm.DB, authorID uint, points int) models.Post {
t.Helper()
post := model.Post{
post := models.Post{
UserID: authorID,
BoardID: 1,
Title: "悬赏测试",
Content: "内容",
PostType: model.PostTypeBounty,
PostType: models.PostTypeBounty,
BountyPoints: points,
BountyStatus: model.BountyStatusOpen,
Status: model.ContentStatusPublished,
BountyStatus: models.BountyStatusOpen,
Status: models.ContentStatusPublished,
}
if err := db.Create(&post).Error; err != nil {
t.Fatal(err)
@@ -44,7 +44,7 @@ func seedBountyPost(t *testing.T, db *gorm.DB, authorID uint, points int) model.
func seedUser(t *testing.T, db *gorm.DB, id uint, points int) {
t.Helper()
u := model.User{
u := models.User{
ID: id,
Username: "user" + string(rune('0'+id)),
Password: "hash",
@@ -58,7 +58,7 @@ func seedUser(t *testing.T, db *gorm.DB, id uint, points int) {
func seedComment(t *testing.T, db *gorm.DB, postID, userID uint, floor int, status string) {
t.Helper()
c := model.Comment{
c := models.Comment{
PostID: postID,
UserID: userID,
Floor: floor,
@@ -79,25 +79,25 @@ func TestCountEligibleBountyReplies(t *testing.T) {
t.Fatalf("无回复时期望 0得到 %d err=%v", n, err)
}
seedComment(t, db, post.ID, 1, 1, model.ContentStatusPublished)
seedComment(t, db, post.ID, 1, 1, models.ContentStatusPublished)
n, err = CountEligibleBountyReplies(db, post.ID, 1)
if err != nil || n != 0 {
t.Fatalf("楼主自己的回复不应计入,得到 %d", n)
}
seedComment(t, db, post.ID, 2, 2, model.ContentStatusPublished)
seedComment(t, db, post.ID, 2, 2, models.ContentStatusPublished)
n, err = CountEligibleBountyReplies(db, post.ID, 1)
if err != nil || n != 1 {
t.Fatalf("他人 published 回复期望 1得到 %d", n)
}
seedComment(t, db, post.ID, 3, 3, model.ContentStatusPending)
seedComment(t, db, post.ID, 3, 3, models.ContentStatusPending)
n, err = CountEligibleBountyReplies(db, post.ID, 1)
if err != nil || n != 1 {
t.Fatalf("pending 回复不应增加计数,得到 %d", n)
}
seedComment(t, db, post.ID, 0, 4, model.ContentStatusPublished)
seedComment(t, db, post.ID, 0, 4, models.ContentStatusPublished)
n, err = CountEligibleBountyReplies(db, post.ID, 1)
if err != nil || n != 2 {
t.Fatalf("游客回复应计入,得到 %d", n)
@@ -113,7 +113,7 @@ func TestCanRefundBounty(t *testing.T) {
t.Fatalf("无回复时楼主应可退can=%v reason=%q", can, reason)
}
seedComment(t, db, post.ID, 2, 1, model.ContentStatusPublished)
seedComment(t, db, post.ID, 2, 1, models.ContentStatusPublished)
can, reason = CanRefundBounty(&post, false)
if can || reason != bountyRefundBlockReason {
t.Fatalf("有他人回复时楼主不可退can=%v reason=%q", can, reason)
@@ -130,7 +130,7 @@ func TestRefundBountyBlockedForAuthorWithReplies(t *testing.T) {
seedUser(t, db, 1, 0)
seedUser(t, db, 2, 0)
post := seedBountyPost(t, db, 1, 8)
seedComment(t, db, post.ID, 2, 1, model.ContentStatusPublished)
seedComment(t, db, post.ID, 2, 1, models.ContentStatusPublished)
err := RefundBounty(post.ID, 1, false)
if !errors.Is(err, ErrBountyRefundBlocked) {
@@ -146,14 +146,14 @@ func TestRefundBountyAllowedWithoutReplies(t *testing.T) {
if err := RefundBounty(post.ID, 1, false); err != nil {
t.Fatalf("无回复时楼主应可退回err=%v", err)
}
var updated model.Post
var updated models.Post
if err := db.First(&updated, post.ID).Error; err != nil {
t.Fatal(err)
}
if updated.BountyStatus != model.BountyStatusRefunded || updated.BountyPoints != 0 {
if updated.BountyStatus != models.BountyStatusRefunded || updated.BountyPoints != 0 {
t.Fatalf("状态应为 refunded 且积分为 0得到 status=%s points=%d", updated.BountyStatus, updated.BountyPoints)
}
var author model.User
var author models.User
if err := db.First(&author, 1).Error; err != nil {
t.Fatal(err)
}
@@ -167,7 +167,7 @@ func TestRefundBountyAdminBypassWithReplies(t *testing.T) {
seedUser(t, db, 1, 0)
seedUser(t, db, 2, 0)
post := seedBountyPost(t, db, 1, 4)
seedComment(t, db, post.ID, 2, 1, model.ContentStatusPublished)
seedComment(t, db, post.ID, 2, 1, models.ContentStatusPublished)
if err := RefundBounty(post.ID, 99, true); err != nil {
t.Fatalf("管理员应可强制退回err=%v", err)