You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
5.9 KiB
140 lines
5.9 KiB
package console
|
|
|
|
import (
|
|
"yunyan/comm"
|
|
"yunyan/lego/sys/postgres"
|
|
)
|
|
|
|
// 芯片厂商档案(chip_vendor)——原来是 apps/proto/db.proto 里硬编码的 SolutionVendor 枚举,
|
|
// 加一个厂商要同步改三处代码再重新发版,运营自己加不了,故转成表。
|
|
//
|
|
// **Id 就是 CID**(芯片方案标识,十六进制看,如 恒玄=0xABF4),与方案商的 BID、产品的 PID 同一套路:
|
|
// 手工指定的有含义编码、不自增、后台可改。`solution_provider.vendor` 存的就是它。
|
|
//
|
|
// ⚠️ 尚未确定 CID 的厂商先用历史占位 id(杰里=1 / 蓝汛=2 / 博通=4,即原枚举值),
|
|
// 等真实 CID 定下来在后台改号即可(改号会级联更新方案商的 vendor 引用,见 renameChipVendorId)。
|
|
// 主键不能为空,所以「先空着」只能表现为占位值、不能是 0。
|
|
//
|
|
// 用本地 gorm struct 而不是 pb:这张表只服务后台,客户端协议不涉及,
|
|
// 走 pb 就得重新生成 22 个 .pb.go(见 CLAUDE.md 关于 protoc-gen-go 版本的告警),没必要。
|
|
type ChipVendor struct {
|
|
// Id 即 CID:手工指定、不自增。改它会级联改方案商的 vendor,必须走 renameChipVendorId。
|
|
Id uint32 `gorm:"primaryKey;column:id" json:"id"`
|
|
Name string `gorm:"column:name;size:64;index" json:"name"` // 厂商名,如 杰里/蓝汛/恒玄/博通
|
|
Enabled bool `gorm:"column:enabled" json:"enabled"` // 停用后不在方案商的「芯片」下拉里出现,但存量方案商仍显示其名字
|
|
Sort int32 `gorm:"column:sort" json:"sort"` // 列表排序,小的在前;相同则按 id
|
|
Createtime int64 `gorm:"column:createtime" json:"createtime"`
|
|
Updatetime int64 `gorm:"column:updatetime" json:"updatetime"`
|
|
}
|
|
|
|
func (ChipVendor) TableName() string { return comm.TableChipVendor }
|
|
|
|
// chipVendorSeeds 原 SolutionVendor 枚举的 4 个取值。
|
|
// 恒玄的 CID 已知(0xABF4)故直接用作 id;其余三家 CID 未定,沿用原枚举值作占位 id,
|
|
// 后台确定后改号即可。不替它们猜值——CID 要烧进固件,猜错比留占位难查得多。
|
|
var chipVendorSeeds = []ChipVendor{
|
|
{Id: 1, Name: "杰里"},
|
|
{Id: 2, Name: "蓝汛"},
|
|
{Id: 0xABF4, Name: "恒玄"},
|
|
{Id: 4, Name: "博通"},
|
|
}
|
|
|
|
// migrateChipVendorCidToId 一次性迁移:把独立的 cid 列并进主键 id。
|
|
//
|
|
// 上一版把 CID 做成了独立字段(id 自增、cid 另存),本版改成「id 即 CID」。已部署过上一版的库里
|
|
// 存着 id=3 / cid=44020 的恒玄,必须把它搬到 id=44020 并同步改掉方案商的 vendor 引用,
|
|
// 否则方案商会指向一个不存在的芯片厂商。
|
|
//
|
|
// 幂等:迁移完就把 cid 列删掉,之后本函数直接跳过。
|
|
func migrateChipVendorCidToId() error {
|
|
// 探测 cid 列是否还在(不在 = 已迁移过,或本来就是新库)
|
|
var n int64
|
|
if err := postgres.Raw(
|
|
"SELECT COUNT(*) FROM information_schema.columns WHERE table_name=? AND column_name='cid'",
|
|
comm.TableChipVendor).Scan(&n).Error; err != nil {
|
|
return err
|
|
}
|
|
if n == 0 {
|
|
return nil
|
|
}
|
|
type cidRow struct {
|
|
Id uint32 `gorm:"column:id"`
|
|
Cid uint32 `gorm:"column:cid"`
|
|
}
|
|
var rows []cidRow
|
|
if err := postgres.Raw(
|
|
"SELECT id, cid FROM " + comm.TableChipVendor + " WHERE cid <> 0 AND cid <> id").Scan(&rows).Error; err != nil {
|
|
return err
|
|
}
|
|
for _, r := range rows {
|
|
// 目标 id 已被别人占用就跳过,留给人工处理——静默合并两条厂商记录比不迁移危险得多。
|
|
var taken int64
|
|
if err := postgres.Table(comm.TableChipVendor).Where("id=?", r.Cid).Count(&taken).Error; err != nil {
|
|
return err
|
|
}
|
|
if taken > 0 {
|
|
continue
|
|
}
|
|
if err := renameChipVendorId(r.Id, r.Cid); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if res := postgres.Exec("ALTER TABLE " + comm.TableChipVendor + " DROP COLUMN IF EXISTS cid"); res.Error != nil {
|
|
return res.Error
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ensureChipVendorSeed 幂等补种 4 条已知厂商。
|
|
//
|
|
// 按【名称】判存在而不是按 id:id 就是 CID、后台可改,按 id 判会在厂商改过号之后
|
|
// 把旧 id 那条重新种回来,变成同名两条。同时也避开 id 被别的厂商占用的情况。
|
|
func ensureChipVendorSeed() error {
|
|
for _, v := range chipVendorSeeds {
|
|
if res := postgres.Exec(
|
|
"INSERT INTO "+comm.TableChipVendor+" (id, name, enabled, sort, createtime, updatetime) "+
|
|
"SELECT ?, ?, true, 0, 0, 0 "+
|
|
"WHERE NOT EXISTS (SELECT 1 FROM "+comm.TableChipVendor+" WHERE name=?) "+
|
|
" AND NOT EXISTS (SELECT 1 FROM "+comm.TableChipVendor+" WHERE id=?)",
|
|
v.Id, v.Name, v.Name, v.Id); res.Error != nil {
|
|
return res.Error
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ---- 芯片厂商 CRUD(console 主库,与方案商/品牌商同库)----
|
|
|
|
func dvChipVendors(sys *appConn) (models []*ChipVendor, err error) {
|
|
models = make([]*ChipVendor, 0)
|
|
err = sys.AdminDB().Find(comm.TableChipVendor, &models, "")
|
|
return
|
|
}
|
|
|
|
func dvChipVendor(sys *appConn, id uint32) (model *ChipVendor, err error) {
|
|
model = &ChipVendor{}
|
|
// 用 FindOne:不存在时返回 ErrRecordNotFound,存在性校验才有效(Find 对空结果不报错)。
|
|
err = sys.AdminDB().FindOne(comm.TableChipVendor, model, "id=?", id)
|
|
return
|
|
}
|
|
|
|
func dvAddChipVendor(sys *appConn, model *ChipVendor) (err error) {
|
|
err = sys.AdminDB().Insert(comm.TableChipVendor, model)
|
|
return
|
|
}
|
|
|
|
func dvSaveChipVendor(sys *appConn, model *ChipVendor) (err error) {
|
|
err = sys.AdminDB().Save(comm.TableChipVendor, model)
|
|
return
|
|
}
|
|
|
|
func dvDelChipVendor(sys *appConn, id uint32) (err error) {
|
|
err = sys.AdminDB().Delete(comm.TableChipVendor, "id=?", id)
|
|
return
|
|
}
|
|
|
|
// dvCountProvidersByVendor 统计挂在某芯片厂商下的方案商数量,删除/改号前用它做引用检查。
|
|
func dvCountProvidersByVendor(sys *appConn, vendorId uint32) (n int64, err error) {
|
|
err = sys.AdminDB().Table(comm.TableSolutionProvider).Where("vendor=?", vendorId).Count(&n).Error
|
|
return
|
|
}
|
|
|