// 芯片厂商,对应后端 chip_vendor 表(原 proto 的 SolutionVendor 枚举,2026-09-01 转表)。 // 一个芯片厂商下可能有多套方案,每套方案是一条方案商记录,靠 DBSolutionProvider.vendor 归拢。 // // 以前这里是写死的四条,加一家厂商要同步改三处代码(db.proto 枚举 + 后端 chipVendorNames + // 本文件)再发版;现在改成拉「芯片管理」页维护的表,代码不用动。 // // 缓存是模块级单例:方案商页、芯片管理页共用同一份,避免每个页面各拉一次。 // 增删改后调用 invalidateChipVendors() 让下次 load 重新拉。 import { ref } from 'vue' export interface ChipVendor { id: number // 即 CID:手工指定的十六进制编码(如 0xABF4=恒玄),也是 solution_provider.vendor 指向的值 name: string enabled?: boolean sort?: number createtime?: number updatetime?: number } /** 全部芯片厂商(含已停用的)。停用项仍要留在这里,否则存量方案商的分组会显示成「厂商#N」。 */ export const chipVendors = ref([]) let loaded = false let inflight: Promise | null = null /** * 拉取芯片厂商列表(模块级缓存,重复调用只发一次请求)。 * webApi 由调用方传入——util 不是组件上下文,直接 useApi() 在某些场景下取不到 Nuxt 实例。 */ export async function loadChipVendors( webApi: (method: string, data?: unknown) => Promise, force = false, ): Promise { if (loaded && !force) return // 并发去重:同一帧里多个组件同时 onMounted 拉取,只发一个请求。 if (inflight && !force) return inflight inflight = (async () => { try { const d = await webApi<{ vendors: ChipVendor[] }>('getchipvendors', {}) chipVendors.value = d?.vendors ?? [] loaded = true } catch { // 拉不到就保持空列表:下拉为空比显示一份可能过期的硬编码值更诚实, // 也避免运营在后台删了某厂商后前端还能选到它。 chipVendors.value = [] } finally { inflight = null } })() return inflight } /** 增删改之后调用,让下次 loadChipVendors 重新拉。 */ export function invalidateChipVendors() { loaded = false } /** 可选项:只列启用中的,用于「新建/编辑方案商」的下拉。 */ export function enabledChipVendors(): ChipVendor[] { return chipVendors.value.filter((v) => v.enabled !== false) } /** * id → 厂商名。查不到时回退成「厂商#N」而不是空白——存量方案商指着一个已删除的厂商时, * 显示成 `厂商#2` 至少能看出是数据问题,空白会让人以为没填。 */ export function chipVendorName(v?: number | null): string { const n = Number(v || 0) if (!n) return '未分组' return chipVendors.value.find((x) => x.id === n)?.name ?? ('厂商#' + n) } /** 「名称 (0xCID)」,下拉里用——同名难辨时靠 CID 区分,也让人一眼看到要烧进固件的那个值。 */ export function chipVendorLabel(v?: number | null): string { const n = Number(v || 0) if (!n) return '未分组' const hit = chipVendors.value.find((x) => x.id === n) return hit ? `${hit.name} (0x${n.toString(16).toUpperCase()})` : ('厂商#' + n) }