Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
tanlongsheng 1 year ago
parent
commit
92c60b3905
  1. 6
      lib/data/models/appconfig.dart
  2. 43
      lib/modules/devices/controllers/devices_controller.dart
  3. 32
      lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  4. 4
      lib/modules/ota_upgrade/views/ota_upgrade_view.dart
  5. 43
      lib/modules/settings/controllers/settings_controller.dart
  6. 79
      local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift

6
lib/data/models/appconfig.dart

@ -30,4 +30,10 @@ class AppConfig {
config.products.map((user) => user.devicename).toList();
return names;
}
static DBProduct? getproduct(String name) {
final foundProduct =
config.products.firstWhere((product) => product.devicename == name);
return foundProduct;
}
}

43
lib/modules/devices/controllers/devices_controller.dart

@ -14,31 +14,48 @@ import 'package:get/get_state_manager/src/simple/get_controllers.dart';
*/
class DevicesController extends GetxController {
late final BleManager _bleManager;
late final Map<int, List<UserDevice>> devices;
// 修改为响应式变量
final RxMap<int, List<UserDevice>> devices = <int, List<UserDevice>>{}.obs;
// 或者使用这种方式
// final Rx<Map<int, List<UserDevice>>> devices = Rx<Map<int, List<UserDevice>>>({});
@override
void onInit() {
super.onInit();
_bleManager = Get.find<BleManager>();
// 在初始化时加载设备数据
_loadDevices();
}
@override
void onClose() {
super.onClose();
// 加载设备数据
void _loadDevices() {
devices.clear();
for (var device in User.instance.devices) {
if (!devices.containsKey(device.id)) {
if (!devices.containsKey(device.devicetype)) {
devices[device.devicetype] = [];
}
devices[device.devicetype]!.add(device);
}
}
@override
void onClose() {
super.onClose();
// onClose 中不应该修改数据,这里应该是清理资源
}
void unbindearphone(UserDevice device) async {
final response = await Api.unbinddevice({
"id": device.id,
});
if (response != null) {
devices[device.devicetype]!.remove(device);
// 响应式更新
devices[device.devicetype]?.remove(device);
devices.refresh(); // 触发UI更新
User.instance.removeUserDevice(device.id);
_bleManager.clearPairedDevices();
_bleManager.disconnect();
@ -48,4 +65,18 @@ class DevicesController extends GetxController {
return;
}
}
// 添加设备
void addDevice(UserDevice device) {
if (!devices.containsKey(device.devicetype)) {
devices[device.devicetype] = [];
}
devices[device.devicetype]!.add(device);
devices.refresh(); // 触发UI更新
}
// 获取指定类型的设备列表
List<UserDevice> getDevicesByType(int deviceType) {
return devices[deviceType] ?? [];
}
}

32
lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart

@ -1,4 +1,5 @@
import 'package:classic_bluetooth/classic_bluetooth.dart';
import 'package:voitrans/data/models/appconfig_model.dart';
import '/routes/app_routes.dart';
import 'package:logger/web.dart';
import 'package:flutter/material.dart';
@ -12,6 +13,7 @@ import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:ota/ota.dart';
import '../../../data/services/ble_manager.dart';
import '../../../data/models/appconfig.dart';
class OtaUpgradeController extends GetxController {
static const int NOT_STARTED = -1; // 未开始
@ -193,24 +195,26 @@ class OtaUpgradeController extends GetxController {
_address = connectedDevices.first.address;
}
// API请求
final response = await Api.getproduct({
"id": deviceInfo.firmwareProductId,
});
DBProduct? product = AppConfig.getproduct("DeapSound");
// 处理API响应
if (response['product'] == null) {
throw const FormatException('API 响应格式错误');
}
// // API请求
// final response = await Api.getproduct({
// "id": deviceInfo.firmwareProductId,
// });
// // 处理API响应
// if (response['product'] == null) {
// throw const FormatException('API 响应格式错误');
// }
final resp = OtaConfigResp.fromJson(response);
Logger().d('getequipmentinfo,resp.systemversion: ${resp.systemversion}');
latestVersion.value = resp.systemversion!;
updatedescription.value = resp.updatedescription!;
updatepackageaddress = resp.updatepackageaddress!;
// final resp = OtaConfigResp.fromJson(response);
// Logger().d('getequipmentinfo,resp.systemversion: ${resp.systemversion}');
latestVersion.value = product?.version ?? "";
// updatedescription.value = resp.updatedescription!;
updatepackageaddress = product!.updatepackageaddress!;
// 版本检查
bool isUpdate = _isNewVersionAvailable(resp.systemversion!);
bool isUpdate = _isNewVersionAvailable(product.version!);
if (isUpdate) {
await _bleManager.setEnterOta(true);

4
lib/modules/ota_upgrade/views/ota_upgrade_view.dart

@ -187,8 +187,8 @@ class OtaUpgradeView extends GetView<OtaUpgradeController> {
),
child: Image.asset(
isDarkMode
? 'assets/images/headphone_dark.png'
: 'assets/images/headphone_light.png',
? 'assets/images/headphone_new3.png'
: 'assets/images/headphone_new4.png',
height: 100.h,
fit: BoxFit.contain,
),

43
lib/modules/settings/controllers/settings_controller.dart

@ -1,4 +1,3 @@
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
@ -7,15 +6,11 @@ import '../../../core/themes/theme_service.dart';
import '../../../data/services/speech_factory.dart';
import '../models/language_model.dart';
import 'package:logger/logger.dart';
import '../../../data/models/user_Info.dart';
import '../../../data/services/ble_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
import 'package:app_settings/app_settings.dart';
import '../../../data/services/version_update_service.dart';
import '../../common/widgets/version_update_dialog.dart';
@ -128,6 +123,8 @@ class SettingsController extends GetxController {
final appVersion = ''.obs;
final buildNumber = ''.obs;
bool isCheckingUpdate = false; //状态锁,防止重复检查
// 权限相关
// 权限组,用于在UI中显示
final List<Map<String, dynamic>> permissionGroups = [
@ -482,8 +479,15 @@ class SettingsController extends GetxController {
/// 手动检查版本更新
Future<void> checkForUpdate() async {
if (isCheckingUpdate) return;
isCheckingUpdate = true;
// 用于跟踪我们的对话框
bool dialogShown = false;
try {
// 显示加载提示
dialogShown = true;
Get.dialog(
const Center(
child: CircularProgressIndicator(),
@ -494,8 +498,12 @@ class SettingsController extends GetxController {
final versionService = VersionUpdateService.to;
final updateInfo = await versionService.checkForUpdate();
// 关闭加载提示
Get.back();
// 关闭加载提示 - 使用精确的关闭方式
if (dialogShown) {
dialogShown = false;
// 直接关闭最顶层的对话框,不依赖状态判断
Navigator.of(Get.overlayContext!).pop();
}
if (updateInfo.hasUpdate) {
// 显示更新对话框
@ -508,23 +516,34 @@ class SettingsController extends GetxController {
.tr //当前已是最新版本
.replaceAll('{version}', updateInfo.currentVersion),
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.green.withOpacity(0.8),
backgroundColor: Colors.green.withValues(alpha: 0.8),
colorText: Colors.white,
);
}
} catch (e) {
// 关闭加载提示
if (Get.isDialogOpen == true) {
Get.back();
// 关闭加载提示 - 异常情况下的可靠关闭
if (dialogShown) {
dialogShown = false;
try {
// 尝试直接关闭
Navigator.of(Get.overlayContext!).pop();
} catch (popError) {
// 如果直接关闭失败,使用备用方案
if (Get.isDialogOpen == true) {
Get.back();
}
}
}
Get.snackbar(
'error'.tr,
'networkErrorRetry'.tr, // 网络错误,请稍后重试
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.8),
backgroundColor: Colors.red.withValues(alpha: 0.8),
colorText: Colors.white,
);
} finally {
isCheckingUpdate = false;
}
}
}

79
local_plugins/chat_api/ios/chat_api/Sources/chat_api/SystemFunctionHandler.swift

@ -4,6 +4,7 @@ import EventKit
import CoreLocation
import MessageUI
import location_service
import user_portrait // 添加这行
/// 结果结构体
public struct Result {
@ -65,6 +66,9 @@ public class SystemFunctionHandler: NSObject {
// 注册打开录音机功能
registerOpenRecorderFunction(client: client)
// 注册用户画像更新功能
registerSetUserProfileFieldFunction(client: client)
} catch {
// 静默处理错误
}
@ -720,3 +724,78 @@ private class OpenRecorderHandler: FunctionHandler {
// private enum LocationError: Error {
// ...
// }
/// 注册设置用户画像字段函数
private func registerSetUserProfileFieldFunction(client: MCPClient) {
let parameters: [String: Any] = [
"type": "object",
"properties": [
"key": [
"type": "string",
"description": "画像字段名,例如:age、tone、工作经历、device_preference"
],
"value": [
"type": "string",
"description": "字段对应的值"
]
],
"required": ["key", "value"]
]
let handler = SetUserProfileFieldHandler()
_ = client.registerLocalFunction(
name: "set_user_profile_field",
description: "设置或更新用户画像中的某一个字段",
parameters: parameters,
handler: handler
)
}
/// 设置用户画像字段处理器
private class SetUserProfileFieldHandler: FunctionHandler {
func handle(arguments: [String: Any]) async throws -> String {
guard let key = arguments["key"] as? String,
let value = arguments["value"] as? String else {
throw ChatApiException("缺少必要参数:key 和 value")
}
// 验证参数
if key.isEmpty {
throw ChatApiException("画像字段名不能为空")
}
if value.isEmpty {
throw ChatApiException("字段值不能为空")
}
let result = await setUserProfileField(key: key, value: value)
return "{\"result\": \"\(result.message)\", \"key\": \"\(key)\", \"value\": \"\(value)\"}\"}"
}
private func setUserProfileField(key: String, value: String) async -> Result {
return await withCheckedContinuation { continuation in
DispatchQueue.main.async {
do {
// 使用 UserPortrait 单例设置画像字段
UserPortrait.shared.set(key: key, value: value)
// 发送通知给其他模块
UserPortrait.shared.sendUpdateNotification(key: key, value: value)
print("[SetUserProfileFieldHandler] 成功设置用户画像字段: \(key) = \(value)")
continuation.resume(returning: Result(
success: true,
message: "成功设置用户画像字段 \(key) 为 \(value)"
))
} catch {
print("[SetUserProfileFieldHandler] 设置用户画像字段失败: \(error.localizedDescription)")
continuation.resume(returning: Result(
success: false,
message: "设置用户画像字段失败:\(error.localizedDescription)"
))
}
}
}
}
}

Loading…
Cancel
Save