package console import ( "yunyan/comm" "yunyan/lego/core" "yunyan/lego/core/cbase" "yunyan/lego/sys/postgres" ) // AppRegistry 应用注册项,存在 console 的公共库(postgres.GetSys(),即 supabase 单库)。 // 每个应用一行,描述「在哪、连哪个业务库、配置事件往哪发」。 // - ServiceDsn → 应用 MySQL 业务库(userdevice/product_stat),仅「重置设备码」清用户绑定时连。 // - DeviceDsn → 已弃用:设备库内容(厂家/产品/设备码)已集中到 console 主库(supabase),注册应用无需再填。 // // 注:DeviceDsn / Redis* 字段为历史保留,已不参与建连。 type AppRegistry struct { Id uint32 `gorm:"primaryKey;autoIncrement;column:id" json:"id"` Name string `gorm:"column:name;size:64" json:"name"` // 显示名,如 "Voitrans(国内)" Region string `gorm:"column:region;size:32" json:"region"` // 区域标记,如 cn/hw BaseUrl string `gorm:"column:base_url;size:255" json:"base_url"` // 应用对外地址(前端跳转/回调) DeviceDsn string `gorm:"column:device_dsn;size:512" json:"device_dsn"` // 已弃用:设备库改走 console 主库(supabase) ServiceDsn string `gorm:"column:service_dsn;size:512" json:"service_dsn"` // 业务库 DSN → 重置设备码时清 userdevice/product_stat RedisAddr string `gorm:"column:redis_addr;size:255" json:"redis_addr"` // Redis 地址,多地址逗号分隔 RedisPwd string `gorm:"column:redis_pwd;size:255" json:"redis_pwd"` RedisDb int `gorm:"column:redis_db" json:"redis_db"` RedisTls bool `gorm:"column:redis_tls" json:"redis_tls"` KeyPrefix string `gorm:"column:key_prefix;size:64" json:"key_prefix"` // Redis key 应用前缀 NatsSubject string `gorm:"column:nats_subject;size:128" json:"nats_subject"` // 配置事件 subject,空则回退默认 NatsStream string `gorm:"column:nats_stream;size:64" json:"nats_stream"` Enabled bool `gorm:"column:enabled" json:"enabled"` // 是否启用(停用的不在切换器展示) Remark string `gorm:"column:remark;size:255" json:"remark"` Createtime int64 `gorm:"column:createtime" json:"createtime"` Updatetime int64 `gorm:"column:updatetime" json:"updatetime"` } func (AppRegistry) TableName() string { return comm.TableAppRegistry } // modelComp 注册库 CRUD(console 的公共库,走全局 postgres.GetSys() —— 即 supabase 单库)。 type modelComp struct { cbase.ModuleCompBase module *Console } func (this *modelComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, opt) this.module = module.(*Console) if err = postgres.CreateTable(comm.TableAppRegistry, &AppRegistry{}); err != nil { this.module.Errorln(err) } if err = this.ensureAccountTable(); err != nil { this.module.Errorln(err) } // 设备管理域表(厂家/产品/设备码/公码/出货单)建在 console 主库(supabase),启动建一次。 // SkipEnsureTables 打开时跳过(如指向已建好表的生产库、只读查看场景)。 if !this.module.options.SkipEnsureTables { if err = ensureDeviceTables(); err != nil { this.module.Errorln(err) } } // 服务配置域三张共享表(全局环境配置/MCP/会议模板)建在 console 主库。 // CreateTable 对已存在的表是幂等空操作(不 AutoMigrate、不改 schema), // 故即便 SkipEnsureTables=true(生产只读 schema)也安全执行——这三张为新表,需确保存在。 if err = ensureConfigTables(); err != nil { this.module.Errorln(err) } return } // listApps 返回全部注册应用(按 id 升序)。 func (this *modelComp) listApps() (models []*AppRegistry, err error) { models = make([]*AppRegistry, 0) err = postgres.Find(comm.TableAppRegistry, &models, "") return } // getApp 按 id 取注册项。 func (this *modelComp) getApp(id uint32) (model *AppRegistry, err error) { model = &AppRegistry{} err = postgres.FindOne(comm.TableAppRegistry, model, "id=?", id) return } // getAppByName 按名称取注册项;埋点信封按应用名校验是否为已注册应用(落库前校验)。 func (this *modelComp) getAppByName(name string) (model *AppRegistry, err error) { model = &AppRegistry{} err = postgres.FindOne(comm.TableAppRegistry, model, "name=?", name) return } // addApp 新增注册项(Insert 后 model.Id 被回填)。 func (this *modelComp) addApp(model *AppRegistry) (err error) { err = postgres.Insert(comm.TableAppRegistry, model) return } // saveApp 更新注册项。 func (this *modelComp) saveApp(model *AppRegistry) (err error) { err = postgres.Save(comm.TableAppRegistry, model) return } // delApp 删除注册项。 func (this *modelComp) delApp(id uint32) (err error) { err = postgres.Delete(comm.TableAppRegistry, "id=?", id) return }