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:
2026-09-02 10:04:03 +00:00
commit 76f266645d
507 changed files with 99891 additions and 0 deletions
+32
View File
@@ -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));
}
}