diff --git a/sc-lktx-backend/internal/pkg/database/init_data.go b/sc-lktx-backend/internal/pkg/database/init_data.go index 8f99f7d..1804f06 100644 --- a/sc-lktx-backend/internal/pkg/database/init_data.go +++ b/sc-lktx-backend/internal/pkg/database/init_data.go @@ -1,15 +1,157 @@ +// 启动时初始化系统默认数据(幂等操作) package database import ( + "crypto/sha256" + "fmt" "log" "com.sclktx/m/v2/internal/common/model" + "com.sclktx/m/v2/internal/pkg/config" + "gorm.io/gorm" ) -// InitData 初始化基础数据 -func InitData(db *gorm.DB) { +// InitData 初始化系统默认数据 +// 角色直接在 User.Role 字段上存储字符串(visitor / employee / guard) +func InitData(db *gorm.DB, systemConfig *config.SystemConfig) error { + // 1. 初始化默认管理员账号(admin / admin123) + var adminCount int64 + db.Model(&model.AdminUser{}).Count(&adminCount) + if adminCount == 0 { + password := fmt.Sprintf("%x", sha256.Sum256([]byte("admin123"))) + db.Create(&model.AdminUser{ + Account: "admin", + Password: password, + Name: "超级管理员", + IsSuper: true, + Status: 1, + }) + log.Println("Default admin created: admin / admin123") + } + + // 1.5 初始化默认用户(ID=1,用于 MockLogin 调试) + var userCount int64 + db.Model(&model.User{}).Where("id = 1").Count(&userCount) + if userCount == 0 { + db.Create(&[]model.User{ + {Openid: "oKdc53TZfIexhCWqUWg-a5i_9lQk", Nickname: "小羊班尼特福迪", RealName: "黄金", Phone: "18780334870", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + {Openid: "oKdc53SDUoKkC62FKbVc4bkDIe8s", Nickname: "Suneast", RealName: "蔡旭东", Phone: "17385767631", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + {Openid: "oKdc53d1WRqQfH19FVuSYxueRFKk", Nickname: "马陈龙", RealName: "马陈龙", Phone: "15228311770", AvatarURL: "http://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lcMUxibpZvwT2Q4IWa4vxEpDelHCcCcg9hUfkVoFyjibp7T5wUpPRkyz7s5QXqNDI6UWzjSib80t24kYxz1nOrTgXxLOca58D9HXo/0?from=appmsg", Role: "employee", Status: 1}, + {Openid: "oKdc53d8D8WFdYa1HvjBfd-DYNN4", Nickname: "Lou", RealName: "邓金路", Phone: "18512811976", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + {Openid: "oKdc53QzvbQBxTjHqa1vLvXzmkRA", Nickname: "访客", RealName: "访客", Phone: "15111111111", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53UBOpgvpu087O803XIMU7zc", Nickname: "高沣", RealName: "高沣", Phone: "15982004934", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53W_y7teyO7UqvOg6UcYazhI", Nickname: "李晨宇", RealName: "李晨宇", Phone: "13911282531", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53Y3vnuaLig0lRq0CiLjT8e0", Nickname: "顾玉龙", RealName: "顾玉龙", Phone: "18866919003", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53ZPIPlMFBjiUwSSMWJoKFqo", Nickname: "许龙飞", RealName: "许龙飞", Phone: "13401147346", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53RlTP4T9GCvH_579T-B9Zcs", Nickname: "谭忻", RealName: "谭忻", Phone: "13908231511", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + // {Openid: "oKdc53TUJoHzf_LY7uvIjiipmNpw", Nickname: "王卿", RealName: "王卿", Phone: "13011811700", AvatarURL: systemConfig.DefaultAvatar, Role: "employee", Status: 1}, + }) + } + + // 2. 初始化默认 Banner(已存在则跳过,按 image_url 去重) + banners := []model.Banner{ + {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lccQHzZScOHm74CUWic2L0mmnUYkThXMTyjk6XMeCmiacZ8FyH8yoeNicac5vImCT8TrYURwsvfZKWufHdHqVibXtoc6oWmbLWvAv0/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 1, IsValid: true}, + {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lcztReQUQC5VhIYPy5wibC6gnxflibgP7hcjw88ZlT2JT3j6RConSxMej5WVWxHEKEK7Z55uKJqb1CRibShyDkmGLQMCSrUo8LrY8/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 2, IsValid: true}, + {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3leNOuzXa7ERs9lWSBZDnrqJlqDnjVdnoaB9PmyUh20dqD72D4xibhNdDPMs7JxHZFJpqficngc2DIDwptgmlZt8lY7jp03La43KM/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 3, IsValid: true}, + {ImageURL: "https://mmbiz.qpic.cn/sz_mmbiz_jpg/XekA4rfc3ldCJC3G64VvKR4T3RVQavicFbvXooEg69icEamMyy4MGiaRlHVibgicvb3J1cGTkHlhD3oZhOiabSoP1u1hzUG4exaIwH6zJymGJk3dM/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 4, IsValid: true}, + // {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3ldkN8Jt8j6S6VScaRn8XjQPqUFcI7c4h7RIh414pfIbAz3pvtcSobK5iaQb0jHJF0Rk0icOUffZsIOhhU9FOjqbxmfJjclfyq0W4/0?from=appmsg", JumpPath: "https://mp.sclktx.com/banner/html/goDianXinZhaPian.html", IsJump: true, Sort: 1, IsValid: true}, + // {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lcOQhS7EPGLdNibSPiaFMiaiaRlsia9szOfBO6FB4rhySpickWBjLqphAnPTvRMFWpg14BbPE9GrI7zia5SAwoiaRlgicymRdWeicbkSRTEo/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 2, IsValid: true}, + // {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lcb48yfFVD6UTLSBzVhn0PE7vDicgTCP4RUfhUeEuJxwzQ0bib7VFagO8ZiapuEfOiadtW2Z7aWBcBzDQKP904nZzK4yObg90OL0GY/0?from=appmsg", JumpPath: "https://mp.sclktx.com/banner/html/goFireFighting.html", IsJump: true, Sort: 3, IsValid: true}, + // {ImageURL: "https://mmbiz.qpic.cn/sz_mmbiz_jpg/XekA4rfc3lfCJtj6yQP5BepYf4ACE5WXCBlaGoLnZ7DWneO4nRqYL5oYMYmibiaG7JwlZUbPHLC9OMJicmUMlN9aQxDgdDICxibsbXZmTcBjanQ/0?from=appmsg", JumpPath: "https://mp.sclktx.com/banner/html/goSafeLaw.html", IsJump: true, Sort: 4, IsValid: true}, + // {ImageURL: "https://mmbiz.qpic.cn/mmbiz_jpg/XekA4rfc3lcLOadSAicKvm3ZXFgn9TtZUOh5tSgaJeQrqs6JhWKfszMHBQhXaicPpgVM09U3dnHBfoEriaM9fKPXYCDvsB2fiaib4TAjXMGV2Ql0/0?from=appmsg", JumpPath: "", IsJump: false, Sort: 5, IsValid: true}, + } + for _, banner := range banners { + var existing model.Banner + if err := db.Where("image_url = ?", banner.ImageURL).First(&existing).Error; err != nil { + if err := db.Create(&banner).Error; err != nil { + log.Printf("Failed to create banner: %v", err) + } + } + } + + // 3. 初始化默认通知(已存在则跳过,按 content 去重) + notices := []model.Notice{ + {Title: "欢迎", Content: "欢迎来到四川凌空天行科技有限公司", Sort: 1, IsValid: true}, + } + for _, notice := range notices { + var existing model.Notice + if err := db.Where("content = ?", notice.Content).First(&existing).Error; err != nil { + if err := db.Create(¬ice).Error; err != nil { + log.Printf("Failed to create notice: %v", err) + } + } + } + + // 4. 初始化默认组织架构(部门树) + if err := initDepartments(db); err != nil { + log.Printf("Failed to init departments: %v", err) + } + + // 5. 初始化默认访客 + var visitorCount int64 + db.Model(&model.Visitor{}).Count(&visitorCount) + userId := uint(1) + if visitorCount == 0 { + visitors := []model.Visitor{ + {UserID: &userId, Name: "张三", Phone: "15111111111", Company: "xxx公司", Gender: 1, IDType: "身份证", IDNumber: "100000000000000001"}, + {UserID: &userId, Name: "李四", Phone: "15222222222", Company: "xxx公司", Gender: 1, IDType: "身份证", IDNumber: "100000000000000002"}, + {UserID: &userId, Name: "王五", Phone: "15333333333", Company: "xxx公司", Gender: 1, IDType: "身份证", IDNumber: "100000000000000003"}, + {UserID: &userId, Name: "赵六", Phone: "15444444444", Company: "xxx公司", Gender: 0, IDType: "身份证", IDNumber: "100000000000000004"}, + } + for _, v := range visitors { + if err := db.Create(&v).Error; err != nil { + log.Printf("Failed to create visitor: %v", err) + } + } + log.Printf("Initialized %d default visitors", len(visitors)) + } + + // 6. 初始化默认物品模板 + var goodsCount int64 + db.Model(&model.GoodsTemplate{}).Where("user_id = ?", userId).Count(&goodsCount) + if goodsCount == 0 { + goods := []model.GoodsTemplate{ + {UserID: userId, Name: "笔记本电脑", Quantity: 1, Model: "ThinkPad X1 Carbon", Remark: ""}, + {UserID: userId, Name: "手机", Quantity: 1, Model: "iPhone 15", Remark: ""}, + {UserID: userId, Name: "U盘", Quantity: 1, Model: "金士顿 64G", Remark: ""}, + {UserID: userId, Name: "工具箱", Quantity: 1, Model: "", Remark: "内含螺丝刀、扳手等工具"}, + } + for _, g := range goods { + if err := db.Create(&g).Error; err != nil { + log.Printf("Failed to create goods template: %v", err) + } + } + log.Printf("Initialized %d default goods templates", len(goods)) + } + + // 7. 初始化默认来访目的 + var visitTypeCount int64 + db.Model(&model.VisitType{}).Count(&visitTypeCount) + if visitTypeCount == 0 { + typeNames := []string{"调研考察", "工作交流", "物流运输", "外协合作", "检查巡查"} + for i, name := range typeNames { + db.Create(&model.VisitType{Name: name, Sort: i, Status: 1}) + } + log.Printf("Initialized %d default visit types", len(typeNames)) + } + + // 8. 初始化默认到访区域 + var areaCount int64 + db.Model(&model.VisitorArea{}).Count(&areaCount) + if areaCount == 0 { + areaNames := []string{"1号楼", "2号楼", "3号楼", "4号楼", "公寓", "食堂"} + for i, name := range areaNames { + db.Create(&model.VisitorArea{Name: name, Sort: i, Status: 1}) + } + log.Printf("Initialized %d default visitor areas", len(areaNames)) + } + + // 8. 初始化默认审批流数据 initProcessDefinitions(db) + + log.Println("System data initialized successfully") + return nil } func initProcessDefinitions(db *gorm.DB) { @@ -56,3 +198,60 @@ func initProcessDefinitions(db *gorm.DB) { } } } + +// initDepartments 初始化默认组织架构(扁平部门列表) +func initDepartments(db *gorm.DB) error { + var count int64 + db.Model(&model.Department{}).Count(&count) + if count > 0 { + return nil + } + + // 1. 创建根部门 + root := model.Department{ + Name: "四川凌空", + Sort: 1, + Status: 1, + } + if err := db.Create(&root).Error; err != nil { + return err + } + + // 2. 创建子部门(根部门的 children) + departments := []string{ + "总经理办公室", + "总体研发部", + "电气系统部", + "软件工程部", + "飞控技术部", + "结构工程部", + "热控系统部", + "运营管理部", + "交付中心", + "综合管理部", + "财务管理部", + "市场开发部", + "人力资源部", + "商务交流部", + "保密办公室", + "体系管理部", + "启昇时代", + "绵阳凌空", + "智能制造部", + } + + for i, name := range departments { + dept := model.Department{ + Name: name, + ParentID: &root.ID, + Sort: i + 1, + Status: 1, + } + if err := db.Create(&dept).Error; err != nil { + return err + } + } + + log.Printf("Initialized root department '%s' with %d children", root.Name, len(departments)) + return nil +}