This commit is contained in:
2026-09-01 17:47:03 +08:00
parent ed6bfdc460
commit 046ce2f1ab
10 changed files with 185 additions and 67 deletions
+34
View File
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -88,6 +89,11 @@ class ModelManager extends ChangeNotifier {
String? _error;
Future<void>? _inFlight;
/// 模型文件/激活集变更版本戳:下载完成或激活变化 +1,
/// UI 据此判断是否需要重建推理 worker(2026-09-01 自动更新引入)
int _revision = 0;
int get revision => _revision;
/// 服务器目录(弹层模型清单展示用)
List<ModelCatalogItem> get catalog => _catalog;
@@ -188,6 +194,8 @@ class ModelManager extends ChangeNotifier {
_models = await _loadBundles(_catalog);
_ready = true;
_error = null;
// 自动更新:已下载/已激活模型发现新版本后台重下(不阻塞目录刷新)
unawaited(autoUpdate());
} catch (e) {
if (!_ready) _error = '模型目录拉取失败:$e';
// 已就绪过则保留旧目录/旧模型,不覆盖 error(下载级错误优先展示)
@@ -233,6 +241,11 @@ class ModelManager extends ChangeNotifier {
_progress.remove(item.datasetId);
_errors.remove(item.datasetId);
_downloadedIds.add(item.datasetId);
_revision++;
// 新版本字节立即生效:自动更新时已激活模型 setActive 会因状态未变
// 提前返回,不在此重载则重建 worker 仍读到旧模型
_models = await _loadBundles(_catalog);
notifyListeners();
await setActive(item.datasetId, true);
return true;
}
@@ -350,11 +363,32 @@ class ModelManager extends ChangeNotifier {
final changed =
active ? _activeIds.add(datasetId) : _activeIds.remove(datasetId);
if (!changed) return;
_revision++;
_models = await _loadBundles(_catalog);
await _saveActive();
notifyListeners();
}
/// 自动更新:已下载/已激活的模型,目录出现新版本时自动重下(保持原激活状态;
/// 未下载的模型不自动拉取,避免无谓流量)。下载进度经 downloadModel 通知。
/// 2026-09-01 用户需求:发布新模型后 App 端自动更新,无需手动触发。
Future<void> autoUpdate() async {
if (_catalog.isEmpty) return;
final tracked = {..._downloadedIds, ..._activeIds};
for (final item in _catalog) {
if (!tracked.contains(item.datasetId)) continue;
if (await _isLocal(item)) continue;
final wasActive = _activeIds.contains(item.datasetId);
try {
final ok = await downloadModel(item);
// 原本未激活:下载完成自动激活后恢复原状态
if (ok && !wasActive) await setActive(item.datasetId, false);
} catch (e) {
debugPrint('[ModelManager] 自动更新失败: ${item.datasetName} $e');
}
}
}
Future<void> _saveActive() async {
try {
final root = await _rootDir();