import 'package:flutter/material.dart'; import 'package:sales_chat/models/group.dart'; import 'package:sales_chat/models/message.dart'; import 'package:sales_chat/services/api_service.dart'; class ChatProvider with ChangeNotifier { final ApiService _apiService; List _groups = []; Map> _messagesByConverse = {}; Group? _currentGroup; bool _isLoading = false; bool _isLoadingMessages = false; String? _error; ChatProvider(this._apiService); List get groups => _groups; Group? get currentGroup => _currentGroup; bool get isLoading => _isLoading; bool get isLoadingMessages => _isLoadingMessages; String? get error => _error; List get currentMessages { if (_currentGroup == null) return []; // 使用第一个文本面板的 ID 作为 converseId final converseId = _currentGroup!.firstTextPanel?.id ?? _currentGroup!.id; return _messagesByConverse[converseId] ?? []; } /// 获取群组的 converseId(第一个文本面板,或以群组 ID 作为备选) String _getConverseIdForGroup(Group group) { return group.firstTextPanel?.id ?? group.id; } Future loadGroups() async { _isLoading = true; _error = null; notifyListeners(); try { _groups = await _apiService.getGroups(); _isLoading = false; notifyListeners(); } catch (e) { _error = 'Failed to load groups'; _isLoading = false; notifyListeners(); } } void selectGroup(Group group) { _currentGroup = group; notifyListeners(); final converseId = _getConverseIdForGroup(group); if (_messagesByConverse[converseId] == null) { loadMessages(converseId); } } void deselectGroup() { _currentGroup = null; notifyListeners(); } Future loadMessages(String converseId, {bool refresh = false}) async { if (_isLoadingMessages) return; _isLoadingMessages = true; notifyListeners(); try { final messages = await _apiService.getMessages( converseId, limit: 50, before: refresh ? null : (_messagesByConverse[converseId]?.first.id), ); if (refresh) { _messagesByConverse[converseId] = messages; } else { _messagesByConverse[converseId] = [ ...messages, ...(_messagesByConverse[converseId] ?? []) ]; } _isLoadingMessages = false; notifyListeners(); } catch (e) { _error = 'Failed to load messages'; _isLoadingMessages = false; notifyListeners(); } } Future sendMessage(String content) async { if (_currentGroup == null || content.isEmpty) return; final converseId = _getConverseIdForGroup(_currentGroup!); final groupId = _currentGroup!.id; try { final message = await _apiService.sendMessage( converseId, content, groupId: groupId, ); _messagesByConverse[converseId] = [ ...(_messagesByConverse[converseId] ?? []), message, ]; notifyListeners(); } catch (e) { _error = 'Failed to send message'; notifyListeners(); } } /// 撤回消息 Future recallMessage(String messageId) async { try { await _apiService.recallMessage(messageId); // 更新本地消息列表 if (_currentGroup != null) { final converseId = _getConverseIdForGroup(_currentGroup!); final messages = _messagesByConverse[converseId]; if (messages != null) { final idx = messages.indexWhere((m) => m.id == messageId); if (idx != -1) { // 标记为已撤回而非删除 final old = messages[idx]; messages[idx] = Message( id: old.id, content: 'Message recalled', author: old.author, groupId: old.groupId, converseId: old.converseId, hasRecall: true, meta: old.meta, createdAt: old.createdAt, updatedAt: old.updatedAt, ); notifyListeners(); } } } return true; } catch (e) { _error = 'Failed to recall message: $e'; notifyListeners(); return false; } } /// 删除消息(管理员) Future deleteMessage(String messageId) async { try { await _apiService.deleteMessage(messageId); // 从本地消息列表中移除 if (_currentGroup != null) { final converseId = _getConverseIdForGroup(_currentGroup!); final messages = _messagesByConverse[converseId]; if (messages != null) { messages.removeWhere((m) => m.id == messageId); notifyListeners(); } } return true; } catch (e) { _error = 'Failed to delete message: $e'; notifyListeners(); return false; } } /// 添加通过 socket.io 接收的消息 void addMessage(Message message) { final converseId = message.converseId; _messagesByConverse[converseId] = [ ...(_messagesByConverse[converseId] ?? []), message, ]; notifyListeners(); } void clearError() { _error = null; notifyListeners(); } }