Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into 唤醒优化

newdev_shunjiawei
fdp 1 year ago
parent
commit
025ac6b26d
  1. 39
      lib/data/models/appconfig_model.dart
  2. 11
      lib/data/services/ble_manager.dart
  3. 9
      lib/data/services/network/api.dart
  4. 19
      lib/modules/agent/views/message_bubble.dart
  5. 24
      lib/modules/devices/controllers/devices_controller.dart
  6. 43
      lib/modules/home/controllers/home_controller.dart
  7. 58
      lib/modules/home/views/home_view.dart
  8. 48
      lib/modules/ota_upgrade/controllers/ota_core_contropller.dart
  9. 36
      lib/modules/pairing/controllers/pairing_controller.dart
  10. 1
      lib/modules/translation/controllers/translation_audiohistory_controller.dart
  11. 6
      lib/modules/translation/controllers/translation_controller.dart
  12. 1
      lib/modules/translation/controllers/translation_detail_controller.dart
  13. 1
      lib/modules/translation/controllers/translation_list_controller.dart
  14. 1
      lib/modules/translation/views/translation_history_view.dart
  15. 1
      lib/modules/translation/views/translation_view.dart

39
lib/data/models/appconfig_model.dart

@ -95,3 +95,42 @@ class DBProduct {
_$DBProductFromJson(json);
Map<String, dynamic> toJson() => _$DBProductToJson(this);
}
//设备类型
enum DeviceType {
/// 未知设备
/// @Description 未知设备
/// @example
unknown(0), //未知设备
/// 经典蓝牙耳机
/// @Description 经典蓝牙耳机
/// @example
classicBluetoothHeadset(1), //经典蓝牙耳机
/// Ble蓝牙耳机 双端
/// @Description Ble蓝牙耳机
/// @example
bleBluetoothDoubleHeadset(2), //Ble蓝牙耳机 双端
/// Ble蓝牙耳机 单端
/// @Description Ble蓝牙耳机
/// @example
bleBluetoothSingleHeadset(3), //Ble蓝牙耳机 单端
/// 智能录音笔
/// @Description 智能录音笔
/// @example
smartVoiceRecorder(4), //智能录音笔
/// 智能眼镜
/// @Description 智能眼镜
/// @example
smartEye(5); //智能眼镜
/// 构造函数
const DeviceType(this.value);
/// 设备类型对应的整数值
final int value;
}

11
lib/data/services/ble_manager.dart

@ -1,13 +1,14 @@
import 'dart:async';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'dart:convert';
import '../../data/models/appconfig.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get_storage/get_storage.dart';
import 'package:get/get.dart';
import 'package:ble_service/ble_service.dart';
import '../../core/utils/logger.dart';
import 'package:get_storage/get_storage.dart';
import 'dart:convert';
import 'package:agent_service/agent_service.dart';
import '../../data/models/appconfig.dart';
import '../../core/utils/logger.dart';
import 'bluetooth_manager.dart';
import 'language_manager.dart';

9
lib/data/services/network/api.dart

@ -154,6 +154,15 @@ class Api {
);
}
// 获取验证码
static getdevices([params]) {
return DioManager().request(
NWMethod.post,
'/api/home/user_getdevices',
params: params,
);
}
//绑定设备
static bindauthcode([params]) {
return DioManager().request(

19
lib/modules/agent/views/message_bubble.dart

@ -159,6 +159,10 @@ class MessageBubble extends GetView<AgentController> {
);
}
if (!isUser && message.isEmpty) {
return _buildTypingIndicator();
}
// 如果是图片消息,显示图片
if (hasImage && imagePath != null) {
// 如果消息是默认的[图片]标记,只显示图片
@ -220,21 +224,6 @@ class MessageBubble extends GetView<AgentController> {
// 判断消息内容,显示特殊卡片
if (!isUser && meta != null) {
// 判断消息类型,显示不同的卡片
// if (meta!.keys.contains('music_play')) {
// final card_music =
// meta!["music_play"]['card_music'] as Map<String, dynamic>?;
// if (card_music != null) {
// final musicId = card_music['id'];
// final musicName = card_music['name'] as String? ?? '未知歌曲';
// final musicUrl = card_music['url'] as String? ?? '';
// final musicSinger = card_music['sgener'] as String? ?? '未知歌手';
// final musicImage = card_music['image'] as String? ?? '';
// final ts = card_music['ts'] as int? ?? 0;
// //音乐卡片
// return buildMusicItem(context, musicId, musicName, musicUrl,
// musicSinger, musicImage, ts);
// }
if (meta!.keys.contains('music_searchandplay_songs')) {
final music_search_songs =
meta!['music_searchandplay_songs'] as Map<String, dynamic>;

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

@ -1,5 +1,7 @@
import 'dart:ffi';
import 'package:voitrans/data/models/appconfig_model.dart';
import '/core/utils/logger.dart';
import '/data/models/user_Info.dart';
import '/data/services/ble_manager.dart';
@ -29,8 +31,16 @@ class DevicesController extends GetxController {
}
// 加载设备数据
void _loadDevices() {
void _loadDevices() async {
devices.clear();
final response = await Api.getdevices();
if (response != null) {
var devices = (response['devices'] as List<dynamic>)
.map((e) => UserDevice.fromJson(e as Map<String, dynamic>))
.toList();
User.instance.devices = devices;
}
for (var device in User.instance.devices) {
if (!devices.containsKey(device.devicetype)) {
devices[device.devicetype] = [];
@ -54,11 +64,13 @@ class DevicesController extends GetxController {
devices[device.devicetype]?.remove(device);
devices.refresh(); // 触发UI更新
User.instance.removeUserDevice(device.id);
_bleManager.clearPairedDevices();
_bleManager.disconnect();
await Future.delayed(const Duration(seconds: 1));
Get.toNamed(Routes.pairing);
if (device.devicemac == _bleManager.deviceInfo.value?.address) {
User.instance.removeUserDevice(device.id);
_bleManager.clearPairedDevices();
_bleManager.disconnect();
await Future.delayed(const Duration(seconds: 1));
Get.toNamed(Routes.pairing);
}
return;
} else {
return;

43
lib/modules/home/controllers/home_controller.dart

@ -8,6 +8,8 @@ import 'package:flutter/material.dart';
import '../../../data/services/bluetooth_manager.dart';
import '../../../data/services/ble_manager.dart';
import '../../../data/services/ota_check_service.dart';
import '../../../data/models/appconfig.dart';
import '../../../data/models/appconfig_model.dart';
/// 连接状态枚举
enum ConnectionStatus {
@ -328,6 +330,47 @@ class HomeController extends GetxController {
return isCharging ? 'charging'.tr : 'notCharging'.tr;
}
/// 获取当前设备类型
/// 返回设备类型,如果无法获取则返回未知类型
DeviceType getCurrentDeviceType() {
try {
final deviceName = getDeviceName();
if (deviceName == 'unknownEquipment'.tr) {
return DeviceType.unknown;
}
// 通过AppConfig获取产品信息
final product = AppConfig.getproduct(deviceName);
if (product != null) {
// 根据产品的devicetype字段返回对应的DeviceType
switch (product.devicetype) {
case 1:
return DeviceType.classicBluetoothHeadset;
case 2:
return DeviceType.bleBluetoothDoubleHeadset;
case 3:
return DeviceType.bleBluetoothSingleHeadset;
case 4:
return DeviceType.smartVoiceRecorder;
case 5:
return DeviceType.smartEye;
default:
return DeviceType.unknown;
}
}
return DeviceType.unknown;
} catch (e) {
Logger.e(_tag, '获取设备类型失败: $e');
return DeviceType.unknown;
}
}
/// 判断当前设备是否为单端耳机
bool isSingleHeadset() {
return getCurrentDeviceType() == DeviceType.bleBluetoothSingleHeadset;
}
String getVersionText() {
return deviceInfo.value?.firmwareVersion.isNotEmpty == true
? deviceInfo.value!.firmwareVersion

58
lib/modules/home/views/home_view.dart

@ -462,6 +462,9 @@ class HomeView extends GetView<HomeController> {
final shouldShowCase =
caseBattery.value > 0 && controller.isFullyConnectedRx.value;
// 判断是否为单端耳机
final isSingleHeadset = controller.isSingleHeadset();
// 使用更紧凑的布局
return Container(
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w),
@ -472,28 +475,43 @@ class HomeView extends GetView<HomeController> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// 左耳机
_buildCompactBatteryItem(
label: 'left'.tr, // 左
batteryLevel: leftBattery.value,
isCharging: leftEarCharging.value,
isDarkMode: isDarkMode,
),
// 单端耳机只显示一个电池信息(优先显示左耳,如果左耳电量为0则显示右耳)
if (isSingleHeadset) ...[
_buildCompactBatteryItem(
label: 'deviceTypeBleBluetoothHeadset'.tr,
batteryLevel: (leftBattery.value > 0 || rightBattery.value == 0)
? leftBattery.value
: rightBattery.value,
isCharging: (leftBattery.value > 0 || rightBattery.value == 0)
? leftEarCharging.value
: rightEarCharging.value,
isDarkMode: isDarkMode,
),
] else ...[
// 双端耳机显示左右两个电池信息
// 左耳机
_buildCompactBatteryItem(
label: 'left'.tr, // 左
batteryLevel: leftBattery.value,
isCharging: leftEarCharging.value,
isDarkMode: isDarkMode,
),
// 分隔线
Container(
height: 30.h,
width: 1,
color: isDarkMode ? Colors.grey[800] : Colors.grey[300],
),
// 分隔线
Container(
height: 30.h,
width: 1,
color: isDarkMode ? Colors.grey[800] : Colors.grey[300],
),
// 右耳机
_buildCompactBatteryItem(
label: 'right'.tr, // 右
batteryLevel: rightBattery.value,
isCharging: rightEarCharging.value,
isDarkMode: isDarkMode,
),
// 右耳机
_buildCompactBatteryItem(
label: 'right'.tr, // 右
batteryLevel: rightBattery.value,
isCharging: rightEarCharging.value,
isDarkMode: isDarkMode,
),
],
// 只有在充电盒电量大于0且设备已连接时才显示充电盒
if (shouldShowCase) ...[

48
lib/modules/ota_upgrade/controllers/ota_core_contropller.dart

@ -288,19 +288,51 @@ class OtaCoreService {
throw "获取设备信息失败,请检查连接";
}
// 验证固件版本格式
final firmwareParts = deviceInfo.firmwareVersion.split('.');
final firstPart = firmwareParts.sublist(0, 3).join('.');
final secondPart = firmwareParts.sublist(3).join('.');
// 获取产品信息以确定设备类型
DBProduct? product = AppConfig.getproduct("DeapSound");
if (product == null) {
throw "无法获取产品信息";
}
Logger().d("firstPart: $firstPart, secondPart: $secondPart");
// 根据设备类型进行不同的版本校验
String currentVersion;
if (product.devicetype == DeviceType.bleBluetoothSingleHeadset.value) {
// 单端耳机:固件版本只有三位数(如:1.2.3)
final firmwareParts = deviceInfo.firmwareVersion.split('.');
if (firmwareParts.length < 3) {
throw "单端耳机固件版本格式错误:${deviceInfo.firmwareVersion},应为三位数格式(如:1.2.3)";
}
currentVersion = firmwareParts.sublist(0, 3).join('.');
Logger().d("单端耳机版本: $currentVersion");
} else if (product.devicetype ==
DeviceType.bleBluetoothDoubleHeadset.value) {
// 双端耳机:固件版本有六位数(如:1.2.3.1.2.3)
final firmwareParts = deviceInfo.firmwareVersion.split('.');
if (firmwareParts.length < 6) {
throw "双端耳机固件版本格式错误:${deviceInfo.firmwareVersion},应为六位数格式(如:1.2.3.1.2.3)";
}
final firstPart = firmwareParts.sublist(0, 3).join('.');
final secondPart = firmwareParts.sublist(3, 6).join('.');
Logger().d("双端耳机版本 - firstPart: $firstPart, secondPart: $secondPart");
if (firstPart != secondPart) {
throw "固件版本格式错误:${deviceInfo.firmwareVersion}";
if (firstPart != secondPart) {
throw "双端耳机固件版本格式错误:${deviceInfo.firmwareVersion},前三位和后三位应该相同";
}
currentVersion = firstPart;
} else {
// 其他设备类型,使用原有逻辑
final firmwareParts = deviceInfo.firmwareVersion.split('.');
if (firmwareParts.length >= 3) {
currentVersion = firmwareParts.sublist(0, 3).join('.');
} else {
currentVersion = deviceInfo.firmwareVersion;
}
Logger().d("其他设备类型版本: $currentVersion");
}
return {
'currentVersion': firstPart,
'currentVersion': currentVersion,
'productId': deviceInfo.firmwareProductId,
'deviceInfo': deviceInfo,
};

36
lib/modules/pairing/controllers/pairing_controller.dart

@ -1,17 +1,18 @@
import 'dart:io';
import 'dart:async';
import 'package:app_settings/app_settings.dart';
import 'package:voitrans/data/models/appconfig_model.dart';
import '/data/models/appconfig.dart';
import '/data/models/user_Info.dart';
import '/data/services/network/api.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'dart:async';
import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../routes/app_routes.dart';
import '../../../core/utils/logger.dart';
import 'dart:io';
import '/data/models/appconfig_model.dart';
import '/data/models/appconfig.dart';
import '/data/models/user_Info.dart';
import '/data/services/network/api.dart';
import '../../../data/services/bluetooth_manager.dart';
import '../../../data/services/ble_manager.dart';
import '../../../core/utils/permission_util.dart';
@ -347,7 +348,7 @@ class PairingController extends GetxController with WidgetsBindingObserver {
void _handleBleStateChange(int state) {
if (_currentState.value == PairingState.waitingBle) {
if (state == 2) {
// BLE已连接
// 2代表BLE已连接
_bleTimeoutTimer?.cancel();
_transition(PairingState.completed);
}
@ -501,32 +502,33 @@ class PairingController extends GetxController with WidgetsBindingObserver {
/// 检查当前状态并决定下一步
void _checkCurrentStatus() async {
try {
// 1. 检查蓝牙状态
// 1. 并行检查蓝牙状态、权限、设备连接
final results = await Future.wait([
_checkBluetoothState(), // 检查蓝牙状态
_checkPermissions(), // 检查权限
_bluetoothManager.refreshDeviceConnection(), // 刷新设备连接
_checkBluetoothState(), // 检查蓝牙是否开启
_checkPermissions(), // 检查蓝牙相关权限
_bluetoothManager.refreshDeviceConnection(), // 刷新设备连接状态
]);
final isBluetoothOk = results[0] as bool;
final arePermissionsOk = results[1] as bool;
//蓝牙没开
if (!isBluetoothOk) {
_setError(
ErrorType.bluetoothOff, 'connectDeepSoundViaSystemBluetooth'.tr);
return;
}
// 2. 检查权限
//权限不够
if (!arePermissionsOk) {
_setError(ErrorType.noPermission, 'pleaseGrantNecessaryPermissions'.tr);
return;
}
// 3. 先刷新设备连接状态,确保获取最新的连接信息
await _bluetoothManager.refreshDeviceConnection();
// 2. 先刷新设备连接状态,确保获取最新的连接信息
//await _bluetoothManager.refreshDeviceConnection();
// 4. 检查经典蓝牙连接
// 3. 检查经典蓝牙连接
final classicDevice = _bluetoothManager.currentDevice;
if (classicDevice == null) {
_transition(PairingState.waitingClassic);
@ -543,7 +545,7 @@ class PairingController extends GetxController with WidgetsBindingObserver {
}
}
/// 新增一个辅助方法来检查蓝牙状态
/// 检查蓝牙状态是否开启
Future<bool> _checkBluetoothState() async {
return _bluetoothManager.bluetoothState != 'off';
}
@ -727,7 +729,7 @@ class PairingController extends GetxController with WidgetsBindingObserver {
// 检查设备名称是否包含 DeepSound 或 DeapSound
final deviceName = device.name;
DBProduct? product;
// 检查是否已有BLE绑定的设备
/// 检查是否已有BLE绑定的设备
if (AppConfig.config.products.isNotEmpty) {
final match = AppConfig.config.products.where(

1
lib/modules/translation/controllers/translation_audiohistory_controller.dart

@ -6,6 +6,7 @@ import 'dart:async';
import '../models/translation_models.dart'; // 添加异步支持
//音频历史管理
class TranslationAudioHistoryController extends GetxController {
// 引用主翻译控制器,以访问历史记录数据
final TranslationController translationController =

6
lib/modules/translation/controllers/translation_controller.dart

@ -1,9 +1,8 @@
import 'dart:io';
import 'dart:async';
import '../../../core/utils/permission_util.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:async';
import 'package:get_storage/get_storage.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
@ -16,6 +15,7 @@ import '../../../data/services/volcano_translation_service.dart';
import '../../../data/services/tts_service.dart';
import '../../../data/services/language_manager.dart';
import '../../../core/utils/logger.dart';
import '../../../core/utils/permission_util.dart';
import '../../../data/services/asr_service.dart';
import '../../../data/services/translation_usage_service.dart';
@ -31,7 +31,7 @@ enum AudioOutputDevice {
speaker, // 强制扬声器
}
/// 翻译控制器 - 负责管理语音识别、翻译和TTS功能
/// 翻译控制器 - 负责管理语音识别、翻译和TTS功能(主控制器)
class TranslationController extends GetxController with WidgetsBindingObserver {
static const String TAG = 'TranslationController';

1
lib/modules/translation/controllers/translation_detail_controller.dart

@ -9,6 +9,7 @@ import 'dart:async';
import '../../../core/utils/logger.dart';
import '../../../data/services/translation_usage_service.dart';
//详情页管理
class TranslationDetailController extends GetxController {
// 依赖注入
final VolcanoAIService _aiService = Get.find<VolcanoAIService>();

1
lib/modules/translation/controllers/translation_list_controller.dart

@ -10,6 +10,7 @@ import '../../../core/utils/permission_util.dart';
import 'package:share_plus/share_plus.dart';
//列表页管理
class TranslationListController extends GetxController {
// 是否还有更多数据
bool isGetMore = true;

1
lib/modules/translation/views/translation_history_view.dart

@ -10,6 +10,7 @@ import 'translation_detail_view.dart';
import '../../../core/theme/app_colors.dart';
import '../../../data/services/language_manager.dart';
//历史记录页面
class TranslationHistoryView
extends GetView<TranslationAudioHistoryController> {
const TranslationHistoryView({Key? key}) : super(key: key);

1
lib/modules/translation/views/translation_view.dart

@ -12,6 +12,7 @@ import '../../../core/theme/app_colors.dart';
import '../../../routes/app_routes.dart';
// import 'package:intl/intl.dart';
//主页面
class TranslationView extends GetView<TranslationController> {
const TranslationView({Key? key}) : super(key: key);

Loading…
Cancel
Save