Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)
含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。 排除 node_modules、构建产物、安装包与 .env 密钥。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// 聊天消息的本地副本。云端只保留 7 天,客户端仍可查看本机历史消息。
|
||||
class ChatLocalStore {
|
||||
ChatLocalStore._();
|
||||
|
||||
static Future<List<Map<String, dynamic>>> load(String conversationId) async {
|
||||
if (conversationId.isEmpty) return [];
|
||||
final p = await SharedPreferences.getInstance();
|
||||
final raw = p.getString('im.local.$conversationId');
|
||||
if (raw == null || raw.isEmpty) return [];
|
||||
try {
|
||||
final list = jsonDecode(raw);
|
||||
if (list is! List) return [];
|
||||
return list.whereType<Map>().map((e) => Map<String, dynamic>.from(e)).toList();
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> save(String conversationId, List<Map<String, dynamic>> items) async {
|
||||
if (conversationId.isEmpty) return;
|
||||
final p = await SharedPreferences.getInstance();
|
||||
final durable = items.where((e) => e['_pending'] != true).map((e) {
|
||||
final copy = Map<String, dynamic>.from(e)..remove('_pending');
|
||||
return copy;
|
||||
}).toList();
|
||||
await p.setString('im.local.$conversationId', jsonEncode(durable));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user