package db import ( "context" "fmt" "log/slog" "bj_power_wms/ent" "golang.org/x/crypto/bcrypt" ) // SeedIfEmpty 首次启动/重置后预置「系统运行必需的基础主数据」,不含任何演示业务数据。 // // 生产环境口径(用户裁决 2026-09-20):种子只允许写入系统跑起来所必需的固定主数据, // 严禁预置演示物料/演示库存/演示账号等假业务数据。具体: // - 区域:库房四大基础分区 Z01~Z04(库存落位的根节点,level=1); // - 管理员账号:admin(初始密码 123456,登录后应立即修改);其余账号由管理员在「账号管理」按需创建、分配角色; // - 接驳台:DOCK01~20(产线,DOCKn↔工位n)+ DOCK21(库房收货),系统预置只读主数据(dock.go 不提供增删改)。 // // 权限与角色不在此:由 handler.SeedRBAC 幂等初始化(reset-all/seed 命令与 POST /api/rbac/seed 共用同一函数)。 func SeedIfEmpty(client *ent.Client) error { ctx := context.Background() // 1. 区域(层级节点 level=1) zones, _ := client.Zone.Query().Count(ctx) if zones == 0 { for _, z := range []struct{ code, name string }{ {"Z01", "待检区"}, {"Z02", "标准存储区"}, {"Z03", "暂存区"}, {"Z04", "退货区"}, } { client.Zone.Create(). SetLevel(1). SetCode(z.code). SetZoneName(z.name). SetZoneCode(z.code). SetParentCode(""). SetStatus("启用"). SaveX(ctx) } slog.Info("seed: zones created") } // 2. 管理员账号(唯一预置账号;初始密码 123456,登录后应立即修改) users, _ := client.User.Query().Count(ctx) if users == 0 { adminHash, _ := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost) client.User.Create(). SetUsername("admin"). SetPassword(string(adminHash)). SetRealName("系统管理员"). SetRole("admin"). SaveX(ctx) slog.Info("seed: admin user created (admin/123456)") } // 3. 接驳台主数据 DOCK01~20(产线, DOCKn↔工位n) + DOCK21(库房) docks, _ := client.Dock.Query().Count(ctx) if docks == 0 { for i := 1; i <= 20; i++ { code := fmt.Sprintf("DOCK%02d", i) client.Dock.Create(). SetDockCode(code). SetName("产线接驳台 " + code + "(工位" + fmt.Sprintf("%d", i) + ")"). SetDockType("line"). SetStationNo(i). SetHasPallet(false). SetStatus("ENABLED"). SaveX(ctx) } client.Dock.Create(). SetDockCode("DOCK21"). SetName("库房收货接驳台"). SetDockType("store"). SetStationNo(0). SetHasPallet(false). SetStatus("ENABLED"). SaveX(ctx) slog.Info("seed: 21 docks created") } return nil }