package db import ( "context" "log/slog" "time" "bj_power_wms/ent" "golang.org/x/crypto/bcrypt" ) // SeedIfEmpty 首次启动时预置基础数据(区域/账号/演示物料与库存) func SeedIfEmpty(client *ent.Client) error { ctx := context.Background() // 1. 区域 zones, _ := client.Zone.Query().Count(ctx) if zones == 0 { for _, z := range []struct{ code, name string }{ {"Z01", "待检区"}, {"Z02", "合格品区"}, {"Z03", "不合格品区"}, {"Z04", "退货区"}, } { client.Zone.Create(). SetZoneCode(z.code). SetZoneName(z.name). SaveX(ctx) } slog.Info("seed: zones created") } // 2. 账号 users, _ := client.User.Query().Count(ctx) if users == 0 { adminHash, _ := bcrypt.GenerateFromPassword([]byte("admin123"), bcrypt.DefaultCost) opHash, _ := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost) client.User.Create(). SetUsername("admin"). SetPassword(string(adminHash)). SetRealName("系统管理员"). SetRole("admin"). SaveX(ctx) client.User.Create(). SetUsername("store1"). SetPassword(string(opHash)). SetRealName("一号库房保管员"). SetRole("operator"). SetDept("库房"). SaveX(ctx) client.User.Create(). SetUsername("insp1"). SetPassword(string(opHash)). SetRealName("质检员一号"). SetRole("inspector"). SetDept("质检"). SaveX(ctx) slog.Info("seed: users created (admin/admin123, store1/123456, insp1/123456)") } // 3. 演示物料与库存 materials, _ := client.Material.Query().Count(ctx) if materials == 0 { mats := []struct { code, name, spec, unit string mode int mtype string isBatch, isSerial bool }{ {"GJ-BAN-001", "10mm钢板(结构件)", "2000x1000x10", "张", 1, "raw", true, false}, {"GJ-GANGGUAN-002", "无缝钢管114x8", "114x8x6000", "根", 1, "raw", true, false}, {"LJ-LUOSI-M16", "M16高强度螺栓", "M16x80 10.9级", "件", 1, "raw", true, false}, {"JM-ZHOUCHENG-6020", "精密轴承6020", "6020-2RS", "套", 2, "raw", false, true}, {"JM-DIANJI-750W", "伺服电机750W", "ECMA-C21307", "台", 2, "raw", false, true}, {"BCP-JIEKOUTI", "接驳体半成品", "-", "件", 2, "semi", false, true}, } for _, m := range mats { client.Material.Create(). SetCode(m.code). SetName(m.name). SetNillableSpec(strPtrNil(m.spec)). SetNillableUnit(strPtrNil(m.unit)). SetManageMode(m.mode). SetIsBatchManaged(m.isBatch). SetIsSerialManaged(m.isSerial). SetMaterialType(m.mtype). SaveX(ctx) } // 演示批次(已检合格) today := time.Now().Format("2006-01-02") client.InventoryBatch.Create(). SetBatchNo("B2026060100001"). SetMaterialCode("GJ-BAN-001"). SetNillableMaterialName(strPtrNil("10mm钢板(结构件)")). SetQuantity(120).SetLockedQty(0). SetNillableProductionDate(strPtrNil("2026-06-01")). SetNillableSupplier(strPtrNil("宝钢供应商")). SetQualityStatus("合格"). SetNillableZoneCode(strPtrNil("Z02")). SaveX(ctx) client.InventoryBatch.Create(). SetBatchNo("B2026060200034"). SetMaterialCode("GJ-GANGGUAN-002"). SetNillableMaterialName(strPtrNil("无缝钢管114x8")). SetQuantity(50).SetLockedQty(0). SetNillableProductionDate(strPtrNil(today)). SetNillableSupplier(strPtrNil("天津钢管")). SetQualityStatus("未检"). SetNillableZoneCode(strPtrNil("Z01")). SaveX(ctx) // 演示 SN(在库) for i := 1; i <= 5; i++ { sn := "SN20260601001" + time.Now().Format("02") client.SerialNumber.Create(). SetSnCode(sn+itoaPad(i)). SetMaterialCode("JM-ZHOUCHENG-6020"). SetStatus("在库"). SetQualityStatus("合格"). SetNillableCurrentZone(strPtrNil("Z02")). SaveX(ctx) } slog.Info("seed: demo materials & stock created") } return nil } func strPtrNil(s string) *string { if s == "" { return nil } return &s } func itoaPad(n int) string { base := "000" return base[:len(base)-lenOfInt(n)] + intToStr(n) } func lenOfInt(n int) int { c := 1 for n >= 10 { n /= 10 c++ } return c } func intToStr(n int) string { if n < 10 { return string(rune('0' + n)) } return intToStr(n/10) + string(rune('0'+n%10)) }