migrate from github
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func createUserInTx(tx *gorm.DB, username, email, password string) error {
|
||||
logrus.Printf("Creating user %s in transaction...", username)
|
||||
|
||||
hashedPwd, err := utils.HashPassword(password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
externalID := utils.GenerateExternalID(utils.ExternalIDContextDocument)
|
||||
|
||||
user := model.User{
|
||||
ExternalID: externalID,
|
||||
Username: username,
|
||||
PasswordHash: hashedPwd,
|
||||
Email: email,
|
||||
Nickname: username,
|
||||
Status: 1,
|
||||
}
|
||||
|
||||
var count int64
|
||||
tx.Model(&model.User{}).Where("email = ?", user.Email).Count(&count)
|
||||
if count == 0 {
|
||||
if err := tx.Create(&user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Printf("User %s created successfully in transaction.", username)
|
||||
} else {
|
||||
logrus.Printf("User %s already exists in transaction.", username)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createUserWithUsername(tx *gorm.DB, username string) error {
|
||||
email := fmt.Sprintf("%s@yoresee.cc", username)
|
||||
password := username
|
||||
return createUserInTx(tx, username, email, password)
|
||||
}
|
||||
|
||||
func createAdminUserInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Creating admin user in transaction...")
|
||||
|
||||
if err := createUserWithUsername(tx, "admin"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Println("Admin permission granted successfully in transaction.")
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/XingfenD/yoresee_doc/internal/constant"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/XingfenD/yoresee_doc/pkg/storage"
|
||||
)
|
||||
|
||||
func initializeConfigInConsul(ctx context.Context) error {
|
||||
registerModeKey := utils.GenConfigKey(
|
||||
constant.ConfigKey_First_System,
|
||||
constant.ConfigKey_Second_Security,
|
||||
constant.ConfigKey_Third_RegisterMode,
|
||||
)
|
||||
|
||||
if _, ok, err := storage.Consul.Get(ctx, registerModeKey); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
if err := storage.Consul.Set(ctx, registerModeKey, constant.RegisterMode_Invite); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func markDatabaseInitializedInConsul(ctx context.Context) error {
|
||||
initializedKey := utils.GenConfigKey(
|
||||
constant.ConfigKey_First_System,
|
||||
constant.ConfigKey_Second_Database,
|
||||
constant.ConfigKey_Third_Initialized,
|
||||
)
|
||||
return storage.Consul.Set(ctx, initializedKey, constant.Database_Initialized_True)
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DocumentInput struct {
|
||||
Title string
|
||||
Content string
|
||||
Summary string
|
||||
ParentID int64
|
||||
Tags []string
|
||||
KnowledgeID *int64
|
||||
}
|
||||
|
||||
func createDocumentWithAllTables(tx *gorm.DB, adminUserID int64, input DocumentInput) (*model.Document, error) {
|
||||
document := model.Document{
|
||||
ExternalID: utils.GenerateExternalID(utils.ExternalIDContextDocument),
|
||||
Title: input.Title,
|
||||
Type: "markdown",
|
||||
Summary: input.Summary,
|
||||
ParentID: input.ParentID,
|
||||
UserID: adminUserID,
|
||||
Content: input.Content,
|
||||
Tags: input.Tags,
|
||||
ViewCount: 0,
|
||||
EditCount: 0,
|
||||
KnowledgeID: input.KnowledgeID,
|
||||
Path: "0",
|
||||
Depth: 0,
|
||||
}
|
||||
|
||||
if err := tx.Create(&document).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := updateDocumentPathDepth(tx, document.ID, document.ParentID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
documentVersion := model.DocumentVersion{
|
||||
DocumentID: document.ID,
|
||||
Version: 1,
|
||||
Title: document.Title,
|
||||
Content: document.Content,
|
||||
UserID: adminUserID,
|
||||
ChangeSummary: "Initial version",
|
||||
}
|
||||
|
||||
if err := tx.Create(&documentVersion).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &document, nil
|
||||
}
|
||||
|
||||
func initializeDocumentsInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Initializing default documents in transaction...")
|
||||
|
||||
var adminUser model.User
|
||||
if err := tx.Where("username = ?", "admin").First(&adminUser).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var count int64
|
||||
tx.Model(&model.Document{}).Where("title = ?", "欢迎使用 Yoresee Doc").Count(&count)
|
||||
if count > 0 {
|
||||
logrus.Println("Default document already exists in transaction.")
|
||||
return nil
|
||||
}
|
||||
contentString := "# 欢迎使用 Yoresee Doc\n\n这是您的第一个文档。Yoresee Doc 是一个功能强大的文档管理系统,支持以下特性:\n\n- 📝 富文本编辑\n- 📁 文档分类管理\n- 🔍 全文搜索\n- 👥 协作编辑\n- 📊 版本控制\n- 🔒 权限管理\n\n## 快速开始\n\n1. 点击左侧菜单创建新文档\n2. 使用编辑器撰写内容\n3. 保存文档并分享给团队成员\n\n祝您使用愉快!"
|
||||
|
||||
document := model.Document{
|
||||
ExternalID: utils.GenerateExternalID(utils.ExternalIDContextDocument),
|
||||
Title: "欢迎使用 Yoresee Doc",
|
||||
Type: "markdown",
|
||||
Summary: "Yoresee Doc 系统欢迎文档",
|
||||
ParentID: 0,
|
||||
UserID: adminUser.ID,
|
||||
Content: contentString,
|
||||
Tags: []string{"guide", "welcome"},
|
||||
ViewCount: 0,
|
||||
EditCount: 0,
|
||||
Path: "0",
|
||||
Depth: 0,
|
||||
}
|
||||
|
||||
if err := tx.Create(&document).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := updateDocumentPathDepth(tx, document.ID, document.ParentID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
documentVersion := model.DocumentVersion{
|
||||
DocumentID: document.ID,
|
||||
Version: 1,
|
||||
Title: document.Title,
|
||||
Content: contentString,
|
||||
UserID: adminUser.ID,
|
||||
ChangeSummary: "Initial version",
|
||||
}
|
||||
|
||||
if err := tx.Create(&documentVersion).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Println("Adding child documents to welcome document...")
|
||||
|
||||
childDocumentTitles := []string{
|
||||
"功能介绍",
|
||||
"使用教程",
|
||||
"常见问题",
|
||||
"更新日志",
|
||||
"联系我们",
|
||||
}
|
||||
|
||||
for _, title := range childDocumentTitles {
|
||||
childDoc, err := createDocumentWithAllTables(tx, adminUser.ID, DocumentInput{
|
||||
Title: title,
|
||||
Content: "# " + title + "\n\n这是" + title + "的详细文档内容。",
|
||||
Summary: title + "相关文档",
|
||||
ParentID: document.ID,
|
||||
Tags: []string{"welcome", title},
|
||||
KnowledgeID: nil,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to create child document %s: %v", title, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for k := 1; k <= 2; k++ {
|
||||
grandchildTitle := title + " - 详情" + string(rune('0'+k))
|
||||
_, err := createDocumentWithAllTables(tx, adminUser.ID, DocumentInput{
|
||||
Title: grandchildTitle,
|
||||
Content: "# " + grandchildTitle + "\n\n这是" + grandchildTitle + "的详细文档内容。",
|
||||
Summary: grandchildTitle + "相关文档",
|
||||
ParentID: childDoc.ID,
|
||||
Tags: []string{"welcome", title, "详情"},
|
||||
KnowledgeID: nil,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to create grandchild document %s: %v", grandchildTitle, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Println("Child documents added to welcome document successfully")
|
||||
|
||||
logrus.Println("Default document created successfully in transaction")
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateDocumentPathDepth(tx *gorm.DB, docID int64, parentID int64) error {
|
||||
if parentID == 0 {
|
||||
return tx.Exec(`
|
||||
UPDATE document_metas
|
||||
SET path = (id::text)::ltree, depth = 0
|
||||
WHERE id = ?
|
||||
`, docID).Error
|
||||
}
|
||||
|
||||
type pathDepth struct {
|
||||
Path string
|
||||
Depth int
|
||||
}
|
||||
var parent pathDepth
|
||||
if err := tx.Model(&model.Document{}).
|
||||
Select("path, depth").
|
||||
Where("id = ?", parentID).
|
||||
Take(&parent).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Exec(`
|
||||
UPDATE document_metas
|
||||
SET path = (?::ltree) || (id::text)::ltree, depth = ?
|
||||
WHERE id = ?
|
||||
`, parent.Path, parent.Depth+1, docID).Error
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func initializeKnowledgeBasesInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Initializing default knowledge bases in transaction...")
|
||||
|
||||
var adminUser model.User
|
||||
if err := tx.Where("username = ?", "admin").First(&adminUser).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var count int64
|
||||
tx.Model(&model.KnowledgeBase{}).Where("name = ?", "默认知识库").Count(&count)
|
||||
if count > 0 {
|
||||
logrus.Println("Default knowledge base already exists in transaction.")
|
||||
return nil
|
||||
}
|
||||
|
||||
defaultKnowledgeBase := model.KnowledgeBase{
|
||||
ExternalID: utils.GenerateExternalID(utils.ExternalIDKnowledgeBase),
|
||||
Name: "默认知识库",
|
||||
Description: "系统默认创建的知识库,用于存储常用文档和资料",
|
||||
Cover: "",
|
||||
CreatorUserID: adminUser.ID,
|
||||
IsPublic: false,
|
||||
}
|
||||
|
||||
if err := tx.Create(&defaultKnowledgeBase).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exampleKnowledgeBase := model.KnowledgeBase{
|
||||
ExternalID: utils.GenerateExternalID(utils.ExternalIDKnowledgeBase),
|
||||
Name: "示例知识库",
|
||||
Description: "示例知识库,展示知识库功能",
|
||||
Cover: "",
|
||||
CreatorUserID: adminUser.ID,
|
||||
IsPublic: true,
|
||||
}
|
||||
|
||||
if err := tx.Create(&exampleKnowledgeBase).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Println("Adding documents to default knowledge base...")
|
||||
|
||||
rootDocumentTitles := []string{
|
||||
"项目概述",
|
||||
"系统架构",
|
||||
"开发规范",
|
||||
"API文档",
|
||||
"数据库设计",
|
||||
"前端开发",
|
||||
"后端开发",
|
||||
"测试计划",
|
||||
"部署指南",
|
||||
"安全规范",
|
||||
"用户手册",
|
||||
}
|
||||
|
||||
for _, title := range rootDocumentTitles {
|
||||
rootDoc, err := createDocumentWithAllTables(tx, adminUser.ID, DocumentInput{
|
||||
Title: title,
|
||||
Content: "# " + title + "\n\n这是" + title + "的详细文档内容。",
|
||||
Summary: title + "相关文档",
|
||||
ParentID: 0,
|
||||
Tags: []string{title},
|
||||
KnowledgeID: &defaultKnowledgeBase.ID,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to create root document %s: %v", title, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for j := 1; j <= 3; j++ {
|
||||
childTitle := title + " - 子文档" + string(rune('0'+j))
|
||||
childDoc, err := createDocumentWithAllTables(tx, adminUser.ID, DocumentInput{
|
||||
Title: childTitle,
|
||||
Content: "# " + childTitle + "\n\n这是" + childTitle + "的详细文档内容。",
|
||||
Summary: childTitle + "相关文档",
|
||||
ParentID: rootDoc.ID,
|
||||
Tags: []string{title, "子文档"},
|
||||
KnowledgeID: &defaultKnowledgeBase.ID,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to create child document %s: %v", childTitle, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for k := 1; k <= 2; k++ {
|
||||
grandchildTitle := childTitle + " - 孙文档" + string(rune('0'+k))
|
||||
_, err := createDocumentWithAllTables(tx, adminUser.ID, DocumentInput{
|
||||
Title: grandchildTitle,
|
||||
Content: "# " + grandchildTitle + "\n\n这是" + grandchildTitle + "的详细文档内容。",
|
||||
Summary: grandchildTitle + "相关文档",
|
||||
ParentID: childDoc.ID,
|
||||
Tags: []string{title, "子文档", "孙文档"},
|
||||
KnowledgeID: &defaultKnowledgeBase.ID,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to create grandchild document %s: %v", grandchildTitle, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Println("Documents added to default knowledge base successfully")
|
||||
|
||||
logrus.Println("Default knowledge bases created successfully in transaction")
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/internal/bootstrap"
|
||||
"github.com/XingfenD/yoresee_doc/internal/constant"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/XingfenD/yoresee_doc/pkg/storage"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
initializer := bootstrap.NewInitializer().
|
||||
InitConfig().
|
||||
InitPostgres().
|
||||
InitConsul().
|
||||
RequireConsulEnabled()
|
||||
if err := initializer.Err(); err != nil {
|
||||
logrus.Fatalf("Init db_init failed: %v", err)
|
||||
}
|
||||
defer initializer.Shutdown()
|
||||
|
||||
if isDatabaseInitialized() {
|
||||
logrus.Println("Database already initialized, skipping initialization steps")
|
||||
} else {
|
||||
if err := initializeDatabaseInTransaction(); err != nil {
|
||||
logrus.Fatalf("Database initialization failed: %v", err)
|
||||
}
|
||||
if err := initializeConfigInConsul(context.Background()); err != nil {
|
||||
logrus.Fatalf("Consul config initialization failed: %v", err)
|
||||
}
|
||||
if err := markDatabaseInitializedInConsul(context.Background()); err != nil {
|
||||
logrus.Fatalf("Mark database initialized failed: %v", err)
|
||||
}
|
||||
logrus.Println("Database initialized successfully")
|
||||
}
|
||||
|
||||
logrus.Println("All initialization tasks completed successfully!")
|
||||
}
|
||||
|
||||
func isDatabaseInitialized() bool {
|
||||
value, ok, err := storage.Consul.Get(context.Background(), utils.GenConfigKey(
|
||||
constant.ConfigKey_First_System,
|
||||
constant.ConfigKey_Second_Database,
|
||||
constant.ConfigKey_Third_Initialized,
|
||||
))
|
||||
if err != nil || !ok {
|
||||
return false
|
||||
}
|
||||
return value == constant.Database_Initialized_True
|
||||
}
|
||||
|
||||
func initializeDatabaseInTransaction() error {
|
||||
return utils.WithTransaction(storage.DB, func(tx *gorm.DB) error {
|
||||
if err := initializePermissionsInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := createAdminUserInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := createTestUserIntx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initializeDocumentsInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initializeKnowledgeBasesInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initializeTemplatesInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := createNormalUserInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initializeUserGroupsInTx(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func createTestUserIntx(tx *gorm.DB) error {
|
||||
logrus.Println("Creating test user in transaction...")
|
||||
return createUserWithUsername(tx, "test")
|
||||
}
|
||||
|
||||
func createNormalUserInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Creating 100 users in transaction...")
|
||||
|
||||
for i := 1; i <= 20; i++ {
|
||||
username := "user" + strconv.Itoa(i)
|
||||
if err := createUserWithUsername(tx, username); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var user model.User
|
||||
if err := tx.Where("username = ?", username).First(&user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
userNum := strconv.Itoa(i)
|
||||
logrus.Printf("User%s created successfully with ID: %s in transaction.\n", userNum, user.ExternalID)
|
||||
|
||||
logrus.Printf("Creating knowledge base for user%s...\n", userNum)
|
||||
|
||||
kbExternalID := utils.GenerateExternalID(utils.ExternalIDKnowledgeBase)
|
||||
knowledgeBase := model.KnowledgeBase{
|
||||
ExternalID: kbExternalID,
|
||||
Name: "User" + userNum + "'s Knowledge Base",
|
||||
Description: "Knowledge base created by user" + userNum,
|
||||
CreatorUserID: user.ID,
|
||||
IsPublic: false,
|
||||
}
|
||||
|
||||
var kbCount int64
|
||||
tx.Model(&model.KnowledgeBase{}).Where("name = ?", knowledgeBase.Name).Count(&kbCount)
|
||||
if kbCount == 0 {
|
||||
if err := tx.Create(&knowledgeBase).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Printf("Knowledge base created successfully for user%s: %s\n", userNum, knowledgeBase.Name)
|
||||
} else {
|
||||
logrus.Printf("Knowledge base for user%s already exists.\n", userNum)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func initializePermissionsInTx(tx *gorm.DB) error {
|
||||
// logrus.Println("Starting permission initialization in transaction...")
|
||||
|
||||
// adminSubject := model.Subject{
|
||||
// ID: "1",
|
||||
// Type: model.SubjectTypeUser,
|
||||
// }
|
||||
|
||||
// if err := tx.Where("id = ?", adminSubject.ID).FirstOrCreate(&adminSubject).Error; err != nil {
|
||||
// return err
|
||||
// }
|
||||
// logrus.Println("Admin subject created successfully in transaction.")
|
||||
|
||||
// logrus.Println("Permission initialization completed successfully in transaction.")
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type templateSeed struct {
|
||||
Name string
|
||||
Description string
|
||||
Content string
|
||||
Scope string
|
||||
KnowledgeBaseID *int64
|
||||
Tags []string
|
||||
}
|
||||
|
||||
func initializeTemplatesInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Initializing default templates in transaction...")
|
||||
|
||||
var adminUser model.User
|
||||
if err := tx.Where("username = ?", "admin").First(&adminUser).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var defaultKB model.KnowledgeBase
|
||||
if err := tx.Where("name = ?", "默认知识库").First(&defaultKB).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seeds := []templateSeed{
|
||||
{
|
||||
Name: "个人周报模板",
|
||||
Description: "用于个人每周工作复盘与计划",
|
||||
Content: `# 个人周报
|
||||
|
||||
## 本周完成
|
||||
-
|
||||
|
||||
## 问题与风险
|
||||
-
|
||||
|
||||
## 下周计划
|
||||
- `,
|
||||
Scope: "private",
|
||||
Tags: []string{"个人", "周报"},
|
||||
},
|
||||
{
|
||||
Name: "会议纪要模板",
|
||||
Description: "通用会议记录模板",
|
||||
Content: `# 会议纪要
|
||||
|
||||
## 会议信息
|
||||
- 时间:
|
||||
- 参与人:
|
||||
|
||||
## 讨论内容
|
||||
-
|
||||
|
||||
## 行动项
|
||||
- [ ] `,
|
||||
Scope: "private",
|
||||
Tags: []string{"个人", "会议"},
|
||||
},
|
||||
{
|
||||
Name: "需求评审模板",
|
||||
Description: "知识库内需求评审记录模板",
|
||||
KnowledgeBaseID: &defaultKB.ID,
|
||||
Scope: "knowledge_base",
|
||||
Content: `# 需求评审
|
||||
|
||||
## 背景
|
||||
|
||||
## 目标
|
||||
|
||||
## 方案评审
|
||||
- 优点:
|
||||
- 风险:
|
||||
|
||||
## 结论`,
|
||||
Tags: []string{"知识库", "需求"},
|
||||
},
|
||||
{
|
||||
Name: "技术方案模板",
|
||||
Description: "知识库内技术方案沉淀模板",
|
||||
KnowledgeBaseID: &defaultKB.ID,
|
||||
Scope: "knowledge_base",
|
||||
Content: `# 技术方案
|
||||
|
||||
## 问题定义
|
||||
|
||||
## 方案设计
|
||||
|
||||
## 数据模型
|
||||
|
||||
## 发布计划
|
||||
`,
|
||||
Tags: []string{"知识库", "技术"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, seed := range seeds {
|
||||
if err := createTemplateIfNotExists(tx, adminUser.ID, seed); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Println("Default templates initialized successfully in transaction")
|
||||
return nil
|
||||
}
|
||||
|
||||
func createTemplateIfNotExists(tx *gorm.DB, userID int64, seed templateSeed) error {
|
||||
query := tx.Model(&model.Template{}).
|
||||
Where("user_id = ? AND name = ? AND scope = ?", userID, seed.Name, seed.Scope)
|
||||
if seed.KnowledgeBaseID == nil {
|
||||
query = query.Where("knowledge_base_id IS NULL")
|
||||
} else {
|
||||
query = query.Where("knowledge_base_id = ?", *seed.KnowledgeBaseID)
|
||||
}
|
||||
|
||||
var count int64
|
||||
if err := query.Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
template := model.Template{
|
||||
Name: seed.Name,
|
||||
Description: seed.Description,
|
||||
DocumentType: model.DocumentType_Markdown,
|
||||
Content: seed.Content,
|
||||
UserID: userID,
|
||||
Scope: seed.Scope,
|
||||
KnowledgeBaseID: seed.KnowledgeBaseID,
|
||||
IsPublic: false,
|
||||
Tags: seed.Tags,
|
||||
}
|
||||
return tx.Create(&template).Error
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/XingfenD/yoresee_doc/internal/model"
|
||||
"github.com/XingfenD/yoresee_doc/internal/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type seedUserGroup struct {
|
||||
Name string
|
||||
Description string
|
||||
MemberUsers []string
|
||||
}
|
||||
|
||||
func initializeUserGroupsInTx(tx *gorm.DB) error {
|
||||
logrus.Println("Creating user groups in transaction...")
|
||||
|
||||
adminUser, err := getUserByUsername(tx, "admin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user2, err := getUserByUsername(tx, "user2")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seedGroups := []seedUserGroup{
|
||||
{
|
||||
Name: "Admin Group",
|
||||
Description: "Group for admin only",
|
||||
MemberUsers: []string{"admin"},
|
||||
},
|
||||
{
|
||||
Name: "User2 Group",
|
||||
Description: "Group for user2 only",
|
||||
MemberUsers: []string{"user2"},
|
||||
},
|
||||
{
|
||||
Name: "Admin & User2 Group",
|
||||
Description: "Group for admin and user2",
|
||||
MemberUsers: []string{"admin", "user2"},
|
||||
},
|
||||
{
|
||||
Name: "Empty Group",
|
||||
Description: "Group with no members",
|
||||
MemberUsers: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, seed := range seedGroups {
|
||||
group, err := findOrCreateGroup(tx, seed.Name, seed.Description, adminUser.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, username := range seed.MemberUsers {
|
||||
var userID int64
|
||||
switch username {
|
||||
case "admin":
|
||||
userID = adminUser.ID
|
||||
case "user2":
|
||||
userID = user2.ID
|
||||
default:
|
||||
continue
|
||||
}
|
||||
if err := ensureMembership(tx, group.ID, userID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Println("User groups initialized successfully in transaction.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func getUserByUsername(tx *gorm.DB, username string) (*model.User, error) {
|
||||
var user model.User
|
||||
if err := tx.Where("username = ?", username).First(&user).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func findOrCreateGroup(tx *gorm.DB, name, description string, creatorID int64) (*model.UserGroupMeta, error) {
|
||||
name = strings.TrimSpace(name)
|
||||
if name == "" {
|
||||
return nil, gorm.ErrInvalidValue
|
||||
}
|
||||
|
||||
var group model.UserGroupMeta
|
||||
if err := tx.Where("name = ?", name).First(&group).Error; err == nil {
|
||||
return &group, nil
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
group = model.UserGroupMeta{
|
||||
ExternalID: utils.GenerateExternalID(utils.ExternalIDContextUserGroup),
|
||||
Name: name,
|
||||
Description: strings.TrimSpace(description),
|
||||
CreatorID: creatorID,
|
||||
}
|
||||
if err := tx.Create(&group).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &group, nil
|
||||
}
|
||||
|
||||
func ensureMembership(tx *gorm.DB, groupID, userID int64) error {
|
||||
var count int64
|
||||
if err := tx.Model(&model.MembershipRelation{}).
|
||||
Where("type = ? AND membership_id = ? AND user_id = ?", model.MembershipType_UserGroup, groupID, userID).
|
||||
Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil
|
||||
}
|
||||
return tx.Create(&model.MembershipRelation{
|
||||
Type: model.MembershipType_UserGroup,
|
||||
MembershipID: groupID,
|
||||
UserID: userID,
|
||||
}).Error
|
||||
}
|
||||
Reference in New Issue
Block a user