// Package console 是独立部署的后台控制面模块。 // // 由单例服务(services/console)装配,不接 ETCD。模块内四个组件: // - modelComp console 主库(app_registry)CRUD,走 postgres.GetSys()(supabase 单库) // - registryComp 应用业务库连接管理器:仅「重置设备码」按 X-App-Id 动态连应用 MySQL 业务库并缓存 // - statComp 统计汇总消费端:订阅 analyze 双写到 NATS 的埋点事件,累加落 stats_global_day // - serverComp 自带 gin HTTP 服务:静态页 + 注册表 API + /web/api/api_*(按 X-App-Id 直连应用库)+ 配置事件下发 // // 设计要点见 modules/console/registry.go 与 server.go。本期只收纳【设备管理】域, // account/scope/审计/细粒度权限暂不做(仅超管 + JWT token 鉴权)。 package console import ( "yunyan/comm" "yunyan/lego/core" "yunyan/lego/sys/log" "yunyan/modules" ) func NewModule() core.IModule { return new(Console) } type Console struct { modules.ModuleBase options *Options model *modelComp registry *registryComp server *serverComp stat *statComp deviceCache *deviceCacheComp } func (this *Console) GetType() core.M_Modules { return comm.ModuleConsole } func (this *Console) NewOptions() (options core.IModuleOptions) { return new(Options) } func (this *Console) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) { this.options = options.(*Options) if err = this.ModuleBase.Init(service, module, options); err != nil { return } // console 用这把 key 加密密钥字段写进各应用业务库;业务服务(home/api)启动时用自己的 // ${FIELD_ENCRYPT_KEY} 解密。两端不一致 → 解密必失败。打指纹(不打密钥本身)供两边日志比对。 log.Infof("[Console] 字段加密 key 指纹=%s(须与各业务服务启动日志里的指纹一致)", comm.KeyFingerprint(this.options.EncryptKey)) return } func (this *Console) OnInstallComp() { this.ModuleBase.OnInstallComp() // 注册顺序即初始化顺序:model 先建好注册表,registry 再依赖它按应用建连, // deviceCache 预热设备域只读缓存,server 最后对外(读 handler 走 deviceCache)。 this.model = this.RegisterComp(new(modelComp)).(*modelComp) this.registry = this.RegisterComp(new(registryComp)).(*registryComp) this.stat = this.RegisterComp(new(statComp)).(*statComp) this.deviceCache = this.RegisterComp(new(deviceCacheComp)).(*deviceCacheComp) this.server = this.RegisterComp(new(serverComp)).(*serverComp) }