提交 c2c63647 authored 作者: songchuancai's avatar songchuancai

增加会话名称自动生成

上级 0f950dc7
...@@ -39,12 +39,15 @@ class HomePage extends StatefulWidget { ...@@ -39,12 +39,15 @@ class HomePage extends StatefulWidget {
final bool hideNavigation; final bool hideNavigation;
final OpenAIService? openAIService;
const HomePage({ const HomePage({
super.key, super.key,
this.customTitle, this.customTitle,
this.customDescription, this.customDescription,
this.customImageUrl, this.customImageUrl,
this.hideNavigation = false, this.hideNavigation = false,
this.openAIService,
}); });
@override @override
...@@ -58,7 +61,7 @@ class _HomePageState extends State<HomePage> { ...@@ -58,7 +61,7 @@ class _HomePageState extends State<HomePage> {
String lastWords = ''; String lastWords = '';
final OpenAIService openAIService = OpenAIService(); late OpenAIService openAIService;
String? generatedContent; String? generatedContent;
...@@ -103,6 +106,8 @@ class _HomePageState extends State<HomePage> { ...@@ -103,6 +106,8 @@ class _HomePageState extends State<HomePage> {
initSpeechToText(); initSpeechToText();
_initTts(); _initTts();
openAIService = widget.openAIService ?? OpenAIService();
} }
Future<void> _initializeStorage() async { Future<void> _initializeStorage() async {
...@@ -113,15 +118,23 @@ class _HomePageState extends State<HomePage> { ...@@ -113,15 +118,23 @@ class _HomePageState extends State<HomePage> {
_conversations = await _storageService.getConversations(); _conversations = await _storageService.getConversations();
// 每次进入应用创建一个新的会话 // 每次进入应用创建一个新的会话
_createNewConversation(); _createNewConversation();
// if (_conversations.isEmpty) { // if (_conversations.isEmpty) {
// _createNewConversation(); // _createNewConversation();
// } else { // } else {
// _currentConversation = _conversations.first; // _currentConversation = _conversations.first;
// setState(() { // setState(() {
// messages = _currentConversation.messages; // messages = _currentConversation.messages;
// }); // });
// } // }
} }
...@@ -168,27 +181,34 @@ class _HomePageState extends State<HomePage> { ...@@ -168,27 +181,34 @@ class _HomePageState extends State<HomePage> {
_hasSpeechPermission = await speechToText.initialize( _hasSpeechPermission = await speechToText.initialize(
onStatus: (status) { onStatus: (status) {
print('语音状态: $status'); print('语音状态: $status');
if (status == 'notListening') { if (status == 'notListening') {
setState(() => _isListeningPressed = false); setState(() => _isListeningPressed = false);
} }
}, },
onError: (error) { onError: (error) {
print('语音错误: $error'); print('语音错误: $error');
setState(() => _isListeningPressed = false); setState(() => _isListeningPressed = false);
_showErrorDialog('语音初始化失败,请检查麦克风权限'); _showErrorDialog('语音初始化失败,请检查麦克风权限');
}, },
); );
} catch (e) { } catch (e) {
print('语音初始化错误: $e'); print('语音初始化错误: $e');
_hasSpeechPermission = false; _hasSpeechPermission = false;
} }
setState(() {}); setState(() {});
} }
Future<void> startListening() async { Future<void> startListening() async {
if (!_hasSpeechPermission) { if (!_hasSpeechPermission) {
_showErrorDialog('请先授予麦克风权限'); _showErrorDialog('请先授予麦克风权限');
setState(() => _isListeningPressed = false); setState(() => _isListeningPressed = false);
return; return;
} }
...@@ -202,7 +222,9 @@ class _HomePageState extends State<HomePage> { ...@@ -202,7 +222,9 @@ class _HomePageState extends State<HomePage> {
); );
} catch (e) { } catch (e) {
print('开始录音失败: $e'); print('开始录音失败: $e');
setState(() => _isListeningPressed = false); setState(() => _isListeningPressed = false);
_showErrorDialog('启动语音识别失败,请重试'); _showErrorDialog('启动语音识别失败,请重试');
} }
} }
...@@ -409,27 +431,36 @@ class _HomePageState extends State<HomePage> { ...@@ -409,27 +431,36 @@ class _HomePageState extends State<HomePage> {
onTap: () async { onTap: () async {
if (!_isListeningPressed) { if (!_isListeningPressed) {
// 开始录音 // 开始录音
setState(() { setState(() {
_isListeningPressed = true; _isListeningPressed = true;
_currentVoiceText = ''; _currentVoiceText = '';
}); });
await startListening(); await startListening();
} else { } else {
// 停止录音 // 停止录音
setState(() => _isListeningPressed = false); setState(() => _isListeningPressed = false);
await stopListening(); await stopListening();
// 确保有语音文本才处理 // 确保有语音文本才处理
if (_currentVoiceText.isNotEmpty) { if (_currentVoiceText.isNotEmpty) {
setState(() { setState(() {
messages.add(ChatMessage( messages.add(ChatMessage(
text: _currentVoiceText, text: _currentVoiceText,
isUserMessage: true, isUserMessage: true,
)); ));
_isLoading = true; _isLoading = true;
}); });
await _processAIResponse(_currentVoiceText); await _processAIResponse(_currentVoiceText);
} }
setState(() => _currentVoiceText = ''); setState(() => _currentVoiceText = '');
} }
}, },
...@@ -454,7 +485,9 @@ class _HomePageState extends State<HomePage> { ...@@ -454,7 +485,9 @@ class _HomePageState extends State<HomePage> {
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
_isListeningPressed _isListeningPressed
? (_currentVoiceText.isEmpty ? '点击停止' : _currentVoiceText) ? (_currentVoiceText.isEmpty
? '点击停止'
: _currentVoiceText)
: '点击说话', : '点击说话',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
...@@ -904,4 +937,3 @@ class _HomePageState extends State<HomePage> { ...@@ -904,4 +937,3 @@ class _HomePageState extends State<HomePage> {
); );
} }
} }
\ No newline at end of file
...@@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart'; ...@@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../models/app_item.dart'; import '../models/app_item.dart';
import '../services/chat_service.dart';
import '../services/storage_service.dart'; import '../services/storage_service.dart';
import '../home_page.dart'; import '../home_page.dart';
...@@ -22,6 +23,8 @@ class ChatPage extends ConsumerStatefulWidget { ...@@ -22,6 +23,8 @@ class ChatPage extends ConsumerStatefulWidget {
} }
class _ChatPageState extends ConsumerState<ChatPage> { class _ChatPageState extends ConsumerState<ChatPage> {
final OpenAIService openAIService = OpenAIService();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
...@@ -46,6 +49,12 @@ class _ChatPageState extends ConsumerState<ChatPage> { ...@@ -46,6 +49,12 @@ class _ChatPageState extends ConsumerState<ChatPage> {
} }
@override @override
void dispose() {
openAIService.clearConversation();
super.dispose();
}
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
...@@ -78,6 +87,7 @@ class _ChatPageState extends ConsumerState<ChatPage> { ...@@ -78,6 +87,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
customDescription: widget.app.description, customDescription: widget.app.description,
customImageUrl: widget.app.iconUrl, customImageUrl: widget.app.iconUrl,
hideNavigation: true, hideNavigation: true,
openAIService: openAIService,
), ),
); );
} }
......
...@@ -8,6 +8,32 @@ class OpenAIService { ...@@ -8,6 +8,32 @@ class OpenAIService {
// final String apiKey = 'sk-OVjS7VE9mT68Uvg7kSFoMnbU6EU836FO'; // final String apiKey = 'sk-OVjS7VE9mT68Uvg7kSFoMnbU6EU836FO';
// final String appKey = 'app-FRP2s2wSx01rsE67'; // final String appKey = 'app-FRP2s2wSx01rsE67';
String? conversationId; String? conversationId;
bool _isFirstMessage = true;
Future<void> _generateConversationName() async {
if (conversationId == null) return;
var prefs = await SharedPreferences.getInstance();
var storageService = StorageService(prefs);
String appKey = storageService.getWorkbenchToken() ?? '';
try {
final response = await http.post(
Uri.parse('$baseUrl/api/conversations/$conversationId/name'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $appKey',
},
body: jsonEncode({"auto_generate": true}),
);
if (response.statusCode != 200) {
print('生成会话名称失败: ${response.statusCode}');
}
} catch (e) {
print('生成会话名称异常: $e');
}
}
Stream<String> chatGPTAPI(String message) async* { Stream<String> chatGPTAPI(String message) async* {
final client = http.Client(); final client = http.Client();
...@@ -85,11 +111,16 @@ class OpenAIService { ...@@ -85,11 +111,16 @@ class OpenAIService {
} catch (e) { } catch (e) {
throw Exception(e.toString()); throw Exception(e.toString());
} finally { } finally {
if (_isFirstMessage && conversationId != null) {
await _generateConversationName();
_isFirstMessage = false;
}
client.close(); client.close();
} }
} }
void clearConversation() { void clearConversation() {
conversationId = null; conversationId = null;
_isFirstMessage = true;
} }
} }
...@@ -9,12 +9,12 @@ import audioplayers_darwin ...@@ -9,12 +9,12 @@ import audioplayers_darwin
import flutter_tts import flutter_tts
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import speech_to_text_macos import speech_to_text
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SpeechToTextMacosPlugin.register(with: registry.registrar(forPlugin: "SpeechToTextMacosPlugin")) SpeechToTextPlugin.register(with: registry.registrar(forPlugin: "SpeechToTextPlugin"))
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论