258 lines
12 KiB
Go
258 lines
12 KiB
Go
// 启动时初始化系统默认数据(幂等操作)
|
||
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 初始化系统默认数据
|
||
// 角色直接在 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) {
|
||
defs := []model.ProcessDefinition{
|
||
{
|
||
ProcessName: "访客预约审批",
|
||
ProcessCode: "visitor_approval",
|
||
Source: "访客系统",
|
||
Description: "访客预约三级审批:公司接待员工 → 部门指定人 → 分管领导",
|
||
IsActive: true,
|
||
NodesJSON: `[
|
||
{"node_id":"Start","node_name":"发起预约","node_type":0,"user_ids":["$starter"]},
|
||
{"node_id":"Employee","node_name":"公司接待员工审批","node_type":1,"prev_node_ids":["Start"],"user_ids":["$employee_id"]},
|
||
{"node_id":"DeptApprover","node_name":"部门指定人审批","node_type":1,"prev_node_ids":["Employee"],"user_ids":["$dept_approver_ids"]},
|
||
{"node_id":"VPApproval","node_name":"分管领导审批","node_type":1,"prev_node_ids":["DeptApprover"],"user_ids":["$vp_ids"]},
|
||
{"node_id":"End","node_name":"审批完成","node_type":3,"prev_node_ids":["VPApproval"]}
|
||
]`,
|
||
},
|
||
{
|
||
ProcessName: "访客预约审批(兜底)",
|
||
ProcessCode: "visitor_approval_simple",
|
||
Source: "访客系统",
|
||
Description: "访客预约兜底审批:直接推送给全局兜底审批人",
|
||
IsActive: true,
|
||
NodesJSON: `[
|
||
{"node_id":"Start","node_name":"发起预约","node_type":0,"user_ids":["$starter"]},
|
||
{"node_id":"DefaultApproval","node_name":"兜底审批","node_type":1,"prev_node_ids":["Start"],"user_ids":["$default_approver_ids"]},
|
||
{"node_id":"End","node_name":"审批完成","node_type":3,"prev_node_ids":["DefaultApproval"]}
|
||
]`,
|
||
},
|
||
}
|
||
|
||
for _, def := range defs {
|
||
var count int64
|
||
db.Model(&model.ProcessDefinition{}).Where("process_code = ?", def.ProcessCode).Count(&count)
|
||
if count > 0 {
|
||
log.Printf("[init] 流程定义已存在,跳过: %s", def.ProcessCode)
|
||
continue
|
||
}
|
||
if err := db.Create(&def).Error; err != nil {
|
||
log.Printf("[init] 创建流程定义失败 %s: %v", def.ProcessCode, err)
|
||
} else {
|
||
log.Printf("[init] 创建流程定义成功: %s", def.ProcessCode)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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
|
||
}
|