feat: 修复了插件需要外部Provider的问题;加上了一个简易的车控状态返回
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:ai_chat_assistant/ai_chat_assistant.dart';
|
||||
import 'package:ai_chat_assistant/utils/common_util.dart';
|
||||
import 'package:ai_chat_assistant/utils/tts_util.dart';
|
||||
import 'package:basic_intl/intl.dart';
|
||||
@@ -7,11 +8,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import '../enums/vehicle_command_type.dart';
|
||||
import '../enums/message_service_state.dart';
|
||||
import '../enums/message_status.dart';
|
||||
import '../models/chat_message.dart';
|
||||
import '../models/vehicle_cmd.dart';
|
||||
import '../services/chat_sse_service.dart';
|
||||
import '../services/classification_service.dart';
|
||||
import '../services/control_recognition_service.dart';
|
||||
@@ -20,48 +16,72 @@ import '../services/control_recognition_service.dart';
|
||||
import 'command_service.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
// 用单例的模式创建
|
||||
class MessageService extends ChangeNotifier {
|
||||
static const MethodChannel _asrChannel = MethodChannel('com.example.ai_chat_assistant/ali_sdk');
|
||||
|
||||
static final MessageService _instance = MessageService._internal();
|
||||
static MessageService? _instance;
|
||||
|
||||
factory MessageService() => _instance;
|
||||
static MessageService get instance {
|
||||
return _instance ??= MessageService._internal();
|
||||
}
|
||||
|
||||
// 提供工厂构造函数供 Provider 使用
|
||||
factory MessageService() => instance;
|
||||
|
||||
Completer<String>? _asrCompleter;
|
||||
|
||||
MessageService._internal() {
|
||||
_asrChannel.setMethodCallHandler((call) async {
|
||||
switch (call.method) {
|
||||
case "onAsrResult":
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!,
|
||||
text: call.arguments,
|
||||
status: MessageStatus.normal);
|
||||
break;
|
||||
case "onAsrStop":
|
||||
int index = findMessageIndexById(_latestUserMessageId!);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
final message = _messages[index];
|
||||
if (message.text.isEmpty) {
|
||||
removeMessageById(_latestUserMessageId!);
|
||||
return;
|
||||
}
|
||||
if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
|
||||
_asrCompleter!.complete(messages.last.text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
// 注册MethodChannel的handler
|
||||
_asrChannel.setMethodCallHandler(_handleMethodCall);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// 取消注册MethodChannel的handler,避免内存泄漏和意外回调
|
||||
_asrChannel.setMethodCallHandler(null);
|
||||
_asrCompleter?.completeError('Disposed');
|
||||
_asrCompleter = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 提供真正的销毁方法(可选,用于应用退出时)
|
||||
void destroyInstance() {
|
||||
_asrChannel.setMethodCallHandler(null);
|
||||
_asrCompleter?.completeError('Destroyed');
|
||||
_asrCompleter = null;
|
||||
super.dispose();
|
||||
_instance = null;
|
||||
}
|
||||
|
||||
Future<dynamic> _handleMethodCall(MethodCall call) async {
|
||||
switch (call.method) {
|
||||
case "onAsrResult":
|
||||
replaceMessage(
|
||||
id: _latestUserMessageId!, text: call.arguments, status: MessageStatus.normal);
|
||||
break;
|
||||
case "onAsrStop":
|
||||
int index = findMessageIndexById(_latestUserMessageId!);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
final message = _messages[index];
|
||||
if (message.text.isEmpty) {
|
||||
removeMessageById(_latestUserMessageId!);
|
||||
return;
|
||||
}
|
||||
if (_asrCompleter != null && !_asrCompleter!.isCompleted) {
|
||||
_asrCompleter!.complete(messages.last.text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final ChatSseService _chatSseService = ChatSseService();
|
||||
// final LocalTtsService _ttsService = LocalTtsService();
|
||||
// final AudioRecorderService _audioService = AudioRecorderService();
|
||||
// final VoiceRecognitionService _recognitionService = VoiceRecognitionService();
|
||||
final TextClassificationService _classificationService =
|
||||
TextClassificationService();
|
||||
final TextClassificationService _classificationService = TextClassificationService();
|
||||
final VehicleCommandService _vehicleCommandService = VehicleCommandService();
|
||||
|
||||
final List<ChatMessage> _messages = [];
|
||||
@@ -122,11 +142,7 @@ class MessageService extends ChangeNotifier {
|
||||
String addMessage(String text, bool isUser, MessageStatus status) {
|
||||
String uuid = Uuid().v1();
|
||||
_messages.add(ChatMessage(
|
||||
id: uuid,
|
||||
text: text,
|
||||
isUser: isUser,
|
||||
timestamp: DateTime.now(),
|
||||
status: status));
|
||||
id: uuid, text: text, isUser: isUser, timestamp: DateTime.now(), status: status));
|
||||
notifyListeners();
|
||||
return uuid;
|
||||
}
|
||||
@@ -226,8 +242,7 @@ class MessageService extends ChangeNotifier {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
}
|
||||
final vehicleCommandResponse =
|
||||
await _vehicleCommandService.getCommandFromText(text);
|
||||
final vehicleCommandResponse = await _vehicleCommandService.getCommandFromText(text);
|
||||
if (vehicleCommandResponse == null) {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
@@ -235,10 +250,7 @@ class MessageService extends ChangeNotifier {
|
||||
String msg = isChinese
|
||||
? "无法识别车辆控制命令,请重试"
|
||||
: "Cannot recognize the vehicle control command, please try again";
|
||||
replaceMessage(
|
||||
id: _latestAssistantMessageId!,
|
||||
text: msg,
|
||||
status: MessageStatus.normal);
|
||||
replaceMessage(id: _latestAssistantMessageId!, text: msg, status: MessageStatus.normal);
|
||||
} else {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
@@ -259,8 +271,7 @@ class MessageService extends ChangeNotifier {
|
||||
if (_isReplyAborted) {
|
||||
return;
|
||||
}
|
||||
if (command.type == VehicleCommandType.unknown ||
|
||||
command.error.isNotEmpty) {
|
||||
if (command.type == VehicleCommandType.unknown || command.error.isNotEmpty) {
|
||||
continue;
|
||||
}
|
||||
if (command.type == VehicleCommandType.openAC) {
|
||||
@@ -268,8 +279,8 @@ class MessageService extends ChangeNotifier {
|
||||
}
|
||||
bool isSuccess;
|
||||
if (containOpenAC && command.type == VehicleCommandType.changeACTemp) {
|
||||
isSuccess = await Future.delayed(const Duration(milliseconds: 2000),
|
||||
() => processCommand(command, isChinese));
|
||||
isSuccess = await Future.delayed(
|
||||
const Duration(milliseconds: 2000), () => processCommand(command, isChinese));
|
||||
} else {
|
||||
isSuccess = await processCommand(command, isChinese);
|
||||
}
|
||||
@@ -285,8 +296,7 @@ class MessageService extends ChangeNotifier {
|
||||
if (_isReplyAborted || successCommandList.isEmpty) {
|
||||
return;
|
||||
}
|
||||
String controlResponse =
|
||||
await _vehicleCommandService.getControlResponse(successCommandList);
|
||||
String controlResponse = await _vehicleCommandService.getControlResponse(successCommandList);
|
||||
if (_isReplyAborted || controlResponse.isEmpty) {
|
||||
return;
|
||||
}
|
||||
@@ -297,20 +307,22 @@ class MessageService extends ChangeNotifier {
|
||||
Future<bool> processCommand(VehicleCommand command, bool isChinese) async {
|
||||
String msg = "";
|
||||
MessageStatus status = MessageStatus.normal;
|
||||
final (isSuccess, result) = await CommandService.executeCommand(
|
||||
command.type,
|
||||
params: command.params);
|
||||
var commandObjc = VehicleCommand(type: command.type, params: command.params);
|
||||
var client = AIChatAssistantManager.instance.commandClient;
|
||||
if (client == null) {
|
||||
msg = isChinese ? "车辆控制服务未初始化" : "Vehicle control service is not initialized";
|
||||
status = MessageStatus.failure;
|
||||
addMessage(msg, false, status);
|
||||
return false;
|
||||
}
|
||||
final (isSuccess, result) = await client.executeCommand(commandObjc);
|
||||
if (command.type == VehicleCommandType.locateCar) {
|
||||
msg = isChinese
|
||||
? "很抱歉,定位车辆位置失败"
|
||||
: "Sorry, locate the vehicle unsuccessfully";
|
||||
msg = isChinese ? "很抱歉,定位车辆位置失败" : "Sorry, locate the vehicle unsuccessfully";
|
||||
status = MessageStatus.failure;
|
||||
if (isSuccess && result != null && result.isNotEmpty) {
|
||||
String address = result['address'];
|
||||
if (address.isNotEmpty) {
|
||||
msg = isChinese
|
||||
? "已为您找到车辆位置:\"$address\""
|
||||
: "The vehicle location is \"$address\"";
|
||||
msg = isChinese ? "已为您找到车辆位置:\"$address\"" : "The vehicle location is \"$address\"";
|
||||
status = MessageStatus.success;
|
||||
}
|
||||
}
|
||||
@@ -386,8 +398,7 @@ class MessageService extends ChangeNotifier {
|
||||
status: MessageStatus.completed,
|
||||
);
|
||||
} else {
|
||||
replaceMessage(
|
||||
id: messageId, text: responseText, status: MessageStatus.thinking);
|
||||
replaceMessage(id: messageId, text: responseText, status: MessageStatus.thinking);
|
||||
}
|
||||
} catch (e) {
|
||||
abortReply();
|
||||
@@ -401,8 +412,7 @@ class MessageService extends ChangeNotifier {
|
||||
if (index == -1 || messages[index].status != MessageStatus.thinking) {
|
||||
return;
|
||||
}
|
||||
replaceMessage(
|
||||
id: _latestAssistantMessageId!, status: MessageStatus.aborted);
|
||||
replaceMessage(id: _latestAssistantMessageId!, status: MessageStatus.aborted);
|
||||
}
|
||||
|
||||
void removeMessageById(String id) {
|
||||
|
||||
Reference in New Issue
Block a user