feat: 帖子分级置顶(板块/全站)与板块管理员置顶权限、消息管理权限调整

This commit is contained in:
2026-10-15 23:35:30 +08:00
parent e7b0686947
commit 47f87a011c
40 changed files with 822 additions and 207 deletions

View File

@@ -69,6 +69,11 @@ func InitDB(dsn string) error {
return fmt.Errorf("自动迁移失败: %w", err)
}
// 帖子置顶分级:历史全站置顶(pinned=1)升为 2,避免存量置顶帖被降级为板块置顶
if err := preparePostPinLevels(db); err != nil {
return fmt.Errorf("帖子置顶分级迁移失败: %w", err)
}
// RBAC:把初始管理员(id 最小的 admin,通常即首个注册账号)升级为站长;
// 已存在 owner 时不动数据,保证幂等
if err := ensureOwnerRole(db); err != nil {
@@ -180,6 +185,25 @@ func prepareAnnouncementPinnedColumn(db *gorm.DB) error {
return db.Exec(`ALTER TABLE announcements ADD COLUMN pinned boolean NOT NULL DEFAULT false`).Error
}
// preparePostPinLevels 一次性迁移:历史置顶(pinned=1,旧语义=全站置顶)升为 2。
// 新语义下 1=板块置顶、2=全站置顶,若不迁移,存量全站置顶会被降级为板块置顶。
// 用 site_settings 内部键做幂等标记,避免每次启动把新建的板块置顶(=1)误升为全站。
func preparePostPinLevels(db *gorm.DB) error {
const markerKey = "internal_pin_levels_migrated"
var marker int64
if err := db.Model(&SiteSetting{}).Where("key = ?", markerKey).Count(&marker).Error; err != nil {
return err
}
if marker > 0 {
return nil
}
if err := db.Exec(`UPDATE posts SET pinned = 2 WHERE pinned = 1`).Error; err != nil {
return err
}
return db.Exec(`INSERT INTO site_settings (key, value) VALUES (?, ?)
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`, markerKey, "1").Error
}
// prepareSiteSettingValueText 将 site_settings.value 从 varchar(255) 扩为 text(幂等)
func prepareSiteSettingValueText(db *gorm.DB) error {
var tableCount int64