import 'json_util.dart'; /// 一套 AI 模型配置(base url + api key + 模型名) /// /// ⚠️ **不含完整 api key**,只有 [apiKeyMasked]。真正的 key 在服务端, /// 调用由后端代理 —— App 不需要也不该拿到真 key。 class AiConfigItem { const AiConfigItem({ required this.id, required this.name, required this.baseUrl, required this.apiKeyMasked, required this.model, required this.isDefault, required this.editable, required this.fromEnv, required this.ready, }); /// null = 虚拟的「默认」项(值来自服务端 .env) final int? id; final String name; final String baseUrl; final String apiKeyMasked; final String model; /// 是否是「默认」那一项 final bool isDefault; /// 是否可编辑/删除。默认项为 false final bool editable; /// 来源是不是 .env final bool fromEnv; /// 三项是否齐全可用 final bool ready; /// 用于「显示已选中的是哪一项」的稳定标识。 /// /// 默认项没有 id,用 -1 代替 —— 不能直接用 null 当 map key 去比较。 int get selectionKey => id ?? -1; factory AiConfigItem.fromJson(Map json) { return AiConfigItem( id: asNullableInt(json['id']), name: asString(json['name'], fallback: '未命名'), baseUrl: asString(json['baseUrl']), apiKeyMasked: asString(json['apiKeyMasked']), model: asString(json['model']), isDefault: json['isDefault'] == true, editable: json['editable'] != false, fromEnv: json['fromEnv'] == true, ready: json['ready'] == true, ); } }