feat: 管理端板块管理与旧版数据导入,补充部署运营文档
- 新增管理端板块管理页面与后端接口(admin_board) - 新增旧版数据导入:legacyimport 服务、导入面板、importusers 命令行工具 - 聊天用户卡片、板块图标等 UI 组件与界面优化 - 补充 about/公告/1Panel 部署等文档 - gitignore 排除 dist/ 构建产物与 .agents/ 本地工具目录
This commit is contained in:
@@ -62,6 +62,7 @@ func InitDB(dsn string) error {
|
||||
&ChatRoom{}, &ChatRoomMember{}, &ChatMessage{},
|
||||
&PointLedger{}, &PostContentUnlock{}, &PostAttachment{}, &PostAttachmentUnlock{},
|
||||
&PostPollVote{}, &PostLotteryEntry{}, &Ad{},
|
||||
&ImportRecord{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("自动迁移失败: %w", err)
|
||||
}
|
||||
@@ -96,8 +97,20 @@ func InitDB(dsn string) error {
|
||||
`).Error; err != nil {
|
||||
return fmt.Errorf("私聊唯一索引创建失败: %w", err)
|
||||
}
|
||||
|
||||
// 昵称全站唯一(忽略大小写,软删用户不占用),与用户名同级约束:
|
||||
// 保证 @提及 昵称→用户名 映射无歧义。应用层另有友好错误提示(service/auth.go UpdateProfile)。
|
||||
// 存量重名会令本索引创建失败(开发期数据可重置)。
|
||||
if err := db.Exec(`
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_nickname_lower
|
||||
ON users (LOWER(nickname))
|
||||
WHERE deleted_at IS NULL
|
||||
`).Error; err != nil {
|
||||
return fmt.Errorf("昵称唯一索引创建失败(存量数据可能存在重名昵称,请清理或重置数据库): %w", err)
|
||||
}
|
||||
backfillBoardDefaults(db)
|
||||
seedDefaultBoards(db)
|
||||
if err := seedDefaultChatRoom(db); err != nil {
|
||||
if err := EnsureDefaultChatRoom(db); err != nil {
|
||||
return fmt.Errorf("默认群聊大厅初始化失败: %w", err)
|
||||
}
|
||||
if err := ensureDefaultChatMemberships(db); err != nil {
|
||||
@@ -321,13 +334,27 @@ func ensureOwnerRole(db *gorm.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// backfillBoardDefaults 为升级前已存在的板块补齐新字段默认值。
|
||||
// 以 post_policy 为空作为「迁移前旧行」的判定标志:仅对这些行一次性回填
|
||||
// post_policy=all、visible=true;后续已被显式设置过的行(含站长隐藏的板块)不会被覆盖。
|
||||
func backfillBoardDefaults(db *gorm.DB) {
|
||||
if err := db.Model(&Board{}).
|
||||
Where("post_policy = '' OR post_policy IS NULL").
|
||||
Updates(map[string]interface{}{
|
||||
"post_policy": BoardPostPolicyAll,
|
||||
"visible": true,
|
||||
}).Error; err != nil {
|
||||
log.Printf("[model] 板块默认值回填失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// seedDefaultBoards 写入默认板块
|
||||
func seedDefaultBoards(db *gorm.DB) {
|
||||
defaults := []Board{
|
||||
{Name: "综合讨论", Description: "什么都可以聊", Icon: "message-circle", SortOrder: 1},
|
||||
{Name: "技术分享", Description: "分享技术心得与问题", Icon: "code", SortOrder: 2},
|
||||
{Name: "问答求助", Description: "提问与解答", Icon: "help-circle", SortOrder: 3},
|
||||
{Name: "闲聊灌水", Description: "轻松闲聊", Icon: "coffee", SortOrder: 4},
|
||||
{Name: "综合讨论", Description: "什么都可以聊", Icon: "message-circle", SortOrder: 1, PostPolicy: BoardPostPolicyAll, Visible: true},
|
||||
{Name: "技术分享", Description: "分享技术心得与问题", Icon: "code", SortOrder: 2, PostPolicy: BoardPostPolicyAll, Visible: true},
|
||||
{Name: "问答求助", Description: "提问与解答", Icon: "help-circle", SortOrder: 3, PostPolicy: BoardPostPolicyAll, Visible: true},
|
||||
{Name: "闲聊灌水", Description: "轻松闲聊", Icon: "coffee", SortOrder: 4, PostPolicy: BoardPostPolicyAll, Visible: true},
|
||||
}
|
||||
for _, b := range defaults {
|
||||
var count int64
|
||||
@@ -338,8 +365,9 @@ func seedDefaultBoards(db *gorm.DB) {
|
||||
}
|
||||
}
|
||||
|
||||
// seedDefaultChatRoom 确保存在唯一的全站大厅(公开默认群)
|
||||
func seedDefaultChatRoom(db *gorm.DB) error {
|
||||
// EnsureDefaultChatRoom 确保存在唯一的全站大厅(公开默认群)。
|
||||
// 导出供注册链路在启动播种时因空库跳过后就地补建(自愈,不依赖重启)。
|
||||
func EnsureDefaultChatRoom(db *gorm.DB) error {
|
||||
var n int64
|
||||
if err := db.Model(&ChatRoom{}).Where("is_default = ?", true).Count(&n).Error; err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user