diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index d01651e54..a19fc113a 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -1216,4 +1216,6 @@ const Map enUS = { "justNow": "Just now", "minutesAgo": "@minutes minutes ago", "yesterday": "Yesterday", + //补充 + "insufficientIntegral": "Insufficient integral", }; diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index 74d2c9999..5fb101114 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -1115,4 +1115,7 @@ const Map zhCN = { "justNow": "刚刚", "minutesAgo": "@minutes分钟前", "yesterday": "昨天", + + //补充 + "insufficientIntegral": "积分不足", }; diff --git a/lib/data/services/ble_manager.dart b/lib/data/services/ble_manager.dart index 9b4a2cd56..aecf624c9 100644 --- a/lib/data/services/ble_manager.dart +++ b/lib/data/services/ble_manager.dart @@ -777,7 +777,8 @@ class BleManager extends GetxService { "navigationMode": navigationMode, "isttsinterrupt": isTtsInterruptEnabled ? "true" : "false", "aiintegral": 100, //ai积分 - "callingTool": "callingTool".tr + "callingToolText": "callingTool".tr, + "insufficientIntegralText": "insufficientIntegral".tr, }; // 记录日志(不记录敏感信息) diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index a1fe419fd..39662c1b5 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -13,6 +13,7 @@ import 'package:voitrans/data/services/bluetooth_manager.dart'; import 'package:voitrans/data/services/qq_music.dart'; import 'package:flutter_intro/flutter_intro.dart'; import '../../../data/services/novice_guide_service.dart'; +import '../../../routes/app_routes.dart'; import '/core/utils/upload_oss.dart'; import '/data/models/user_Info.dart'; import '/data/services/music_manager.dart'; @@ -782,9 +783,9 @@ class AgentController extends GetxController with WidgetsBindingObserver { case AgentServiceEventType.error: final sessionid = event.data['sessionid'] ?? ''; final message = event.data['message'] ?? ''; - + final code = event.data['code'] ?? 0; // //验证错误码 - if (event.data['code'] == 1000) { + if (code == 1000) { isListening.value = false; isSpeaking.value = false; isProcessing.value = false; @@ -798,6 +799,65 @@ class AgentController extends GetxController with WidgetsBindingObserver { } } Get.snackbar('error'.tr, '${event.data['message']}'); + } else if (code == 2001) { + // 余额不足或需要充值,给出弹窗确认是否跳转充值界面 + final msg = '${event.data['message'] ?? '余额不足,请前往充值'}'; + Get.snackbar('error'.tr, msg); + Get.dialog( + Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(16, 20, 16, 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + '提示', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + Text( + '$msg\n是否前往充值界面?', + textAlign: TextAlign.center, + ), + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.orangeAccent, + foregroundColor: Colors.white, + ), + onPressed: () { + Get.back(); + Get.toNamed(Routes.goodsai); + }, + child: const Text('去充值'), + ), + ), + ], + ), + ), + Positioned( + right: 8, + top: 8, + child: IconButton( + icon: const Icon(Icons.close), + onPressed: () => Get.back(), + ), + ), + ], + ), + ), + barrierDismissible: true, + ); } Logger.e(TAG, '代理服务错误: ${event.data['message']}'); break; diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt index abda6adc4..709208fb7 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt @@ -97,7 +97,8 @@ object AgentService : CoroutineScope { // 会话ID,用于区分不同聊天上下文 private val agentId = "default_agent" //工具调用提示 - private var callingTool = "" + private var callingToolText = "" + private var insufficientIntegralText = "" // 积分不足提示 // 服务端连接 private var serverurl = "" private var usertoken = "" @@ -204,7 +205,8 @@ object AgentService : CoroutineScope { try { serverurl = config["serverurl"]?.toString() ?: ""; usertoken = config["usertoken"]?.toString() ?: ""; - callingTool = config["callingTool"]?.toString() ?: ""; + callingToolText = config["callingToolText"]?.toString() ?: ""; + insufficientIntegralText = config["insufficientIntegralText"]?.toString() ?: ""; aiintegral = config["aiintegral"]?.toString()?.toIntOrNull() ?: 0; // 初始化上下文和服务 @@ -932,6 +934,7 @@ object AgentService : CoroutineScope { hasImage: Boolean = false, imagePath: String? = null ) { + // 如果有正在进行的AI流式输出,先停止它 audioPlayer?.stopAudio() stopAiStream() @@ -1010,6 +1013,7 @@ object AgentService : CoroutineScope { } chatApiService.sendMessageStream( sessionid, + aiintegral, messagesWithSystemPrompt, object : StreamCallback { @@ -1110,6 +1114,10 @@ object AgentService : CoroutineScope { "message" to message ) ) + if(code == 2001){ + ttsService?.speakStream(insufficientIntegralText); + } + //育婴提示 // 标记AI流式输出已完成 _isAiStreaming.set(false) currentAiJob = null @@ -1137,9 +1145,9 @@ object AgentService : CoroutineScope { }else if (name == "qqmusic_pause" || name == "music_pause"){ isplaymusic = false } - Log.d(TAG, "liwei--------------- AI Call onFunctionCall iscallingTool:$iscallingTool callingTool:$callingTool") + Log.d(TAG, "liwei--------------- AI Call onFunctionCall iscallingTool:$iscallingTool callingToolText:$callingToolText") if (iscallingTool) { - ttsService?.speakStream(callingTool) + ttsService?.speakStream(callingToolText) iscallingTool = false } } catch (e: Exception) { diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt index 39edf4c8d..5c0457fdc 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt @@ -78,7 +78,9 @@ class AgentServicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.Stream config["musicServiceType"]?.toString()?.let { intent.putExtra("musicServiceType", it) } config["navigationMode"]?.toString()?.let { intent.putExtra("navigationMode", it) } config["isttsinterrupt"]?.toString()?.let { intent.putExtra("isttsinterrupt", it) } - config["callingTool"]?.toString()?.let { intent.putExtra("callingTool", it) } + config["callingToolText"]?.toString()?.let { intent.putExtra("callingToolText", it) } + config["insufficientIntegralText"]?.toString()?.let { intent.putExtra("insufficientIntegralText", it) } + config["aiintegral"]?.toString()?.let { intent.putExtra("aiintegral", it) } // 添加 supportedLanguages 参数处理 diff --git a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt index db9462134..219ba870b 100644 --- a/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt +++ b/local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleMediaService.kt @@ -68,8 +68,9 @@ class BleMediaService : Service(), CoroutineScope { private const val KEY_SUPPORTED_LANGUAGES = "supportedLanguages" private const val KEY_MUSICSERVICE_TYPE = "musicServiceType" private const val APP_NAVIGATION_MODE = "navigationMode" - private const val APP_CALLING_TOOL = "callingTool" - private const val KEY_AI_INTAGRAL = "aiintegral" + private const val APP_CALLING_TOOL_TEXT = "callingToolText" // 工具调用提示 + private const val APP_INSUFFICIENT_INTEGRAL_TEXT = "insufficientIntegralText" // 积分不足提示 + private const val KEY_AI_INTEGRAL = "aiIntegral" // 积分不足提示 // 用于跟踪服务是否正在运行 private val isRunning = AtomicBoolean(false) @@ -579,8 +580,9 @@ private var companionManager: BleCompanionManager? = null it.getStringExtra(KEY_USER_TOKEN)?.let { value -> config[KEY_USER_TOKEN] = value } it.getStringExtra(KEY_MUSICSERVICE_TYPE)?.let { value -> config[KEY_MUSICSERVICE_TYPE] = value } it.getStringExtra(APP_NAVIGATION_MODE)?.let { value -> config[APP_NAVIGATION_MODE] = value } - it.getStringExtra(APP_CALLING_TOOL)?.let { value -> config[APP_CALLING_TOOL] = value } - it.getStringExtra(KEY_AI_INTAGRAL)?.let { value -> config[KEY_AI_INTAGRAL] = value } + it.getStringExtra(APP_CALLING_TOOL_TEXT)?.let { value -> config[APP_CALLING_TOOL_TEXT] = value } + it.getStringExtra(APP_INSUFFICIENT_INTEGRAL_TEXT)?.let { value -> config[APP_INSUFFICIENT_INTEGRAL_TEXT] = value } + it.getIntExtra(KEY_AI_INTEGRAL, config[KEY_AI_INTEGRAL] as? Int ?: 0) it.getStringExtra("isttsinterrupt")?.let { value -> config["isttsinterrupt"] = value } // 提取 supportedLanguages 参数 @@ -643,8 +645,9 @@ private var companionManager: BleCompanionManager? = null config[KEY_USER_TOKEN] = getConfigString(prefs, KEY_USER_TOKEN, "") config[KEY_MUSICSERVICE_TYPE] = getConfigString(prefs, KEY_MUSICSERVICE_TYPE, "") config[APP_NAVIGATION_MODE] = getConfigString(prefs, APP_NAVIGATION_MODE, "") - config[APP_CALLING_TOOL] = getConfigString(prefs, APP_CALLING_TOOL, "") - config[KEY_AI_INTAGRAL] = getConfigInt(prefs, KEY_AI_INTAGRAL, 0) + config[APP_CALLING_TOOL_TEXT] = getConfigString(prefs, APP_CALLING_TOOL_TEXT, "") + config[APP_INSUFFICIENT_INTEGRAL_TEXT] = getConfigString(prefs, APP_INSUFFICIENT_INTEGRAL_TEXT, "") + config[KEY_AI_INTEGRAL] = getConfigInt(prefs, KEY_AI_INTEGRAL, 0) // 添加 supportedLanguages 参数处理 val supportedLanguagesStr = getConfigString(prefs, KEY_SUPPORTED_LANGUAGES, "") diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index d07c9b2b0..30308b0c3 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -65,7 +65,9 @@ class AgentServiceImpl: NSObject { // 会话ID,用于区分不同聊天上下文 private let agentId = "default_agent" //工具调用提示 - public var callingTool = "" + public var callingToolText = "" // 工具调用提示 + public var insufficientIntegralText = "" // 积分不足提示 + private var navigationMode = "" private var isInitialized: Bool = false @@ -178,8 +180,12 @@ class AgentServiceImpl: NSObject { self.navigationMode = navigationMode } - if let callingTool = config["callingTool"] as? String { - self.callingTool = callingTool + if let callingToolText = config["callingToolText"] as? String { + self.callingToolText = callingToolText + } + + if let insufficientIntegralText = config["insufficientIntegralText"] as? String { + self.insufficientIntegralText = insufficientIntegralText } //加载 isInterrupt 状态 @@ -1807,8 +1813,8 @@ class ChatApiStreamCallback: StreamCallback { ]) if (iscallingTool) { - os_log("收到函数调用: callingTool:%{public}@", log: agentService.logger, type: .info, agentService.callingTool) - agentService.azureTtsHelper?.speakStream(sessionid: sessionid,agentService.callingTool) + os_log("收到函数调用: callingToolText:%{public}@", log: agentService.logger, type: .info, agentService.callingToolText) + agentService.azureTtsHelper?.speakStream(sessionid: sessionid,agentService.callingToolText) iscallingTool = false } diff --git a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt index 5c0e12951..bced9835b 100644 --- a/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt +++ b/local_plugins/chat_api/android/src/main/kotlin/com/yunqiinnovation/chat_api/ChatApiService.kt @@ -347,12 +347,13 @@ class ChatApiService(private val context: android.content.Context? = null) : Cor /** * 发送消息(流式输出)- 兼容JSONArray格式 */ - fun sendMessageStream(sessionid: String,messages: org.json.JSONArray, callback: StreamCallback) { + fun sendMessageStream(sessionid: String,integral: Int, messages: org.json.JSONArray, callback: StreamCallback) { // 1. 立即中止旧会话 abortCurrentSession() - - // 2. 创建新会话 -// val newSessionId = UUID.randomUUID().toString() + if (integral <= 0) { + callback.onError(sessionid,2001,"积分不足") + return + } currSessionId = sessionid sessionCallbacks[sessionid] = callback // 初始化会话统计