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
+33
View File
@@ -0,0 +1,33 @@
import 'package:shared_preferences/shared_preferences.dart';
/// 本地记录各会话已同步到的最大 seq,断线重连后用于 gap fill。
class ImSeqStore {
ImSeqStore._();
static SharedPreferences? _p;
static Future<void> ensure() async {
_p ??= await SharedPreferences.getInstance();
}
static Future<int> lastSeq(String conversationId) async {
if (conversationId.isEmpty) return 0;
await ensure();
return _p?.getInt('im.seq.$conversationId') ?? 0;
}
static Future<void> setLastSeq(String conversationId, int seq) async {
if (conversationId.isEmpty || seq <= 0) return;
await ensure();
final prev = _p?.getInt('im.seq.$conversationId') ?? 0;
if (seq > prev) await _p!.setInt('im.seq.$conversationId', seq);
}
static Future<void> applyItems(String conversationId, Iterable<Map<String, dynamic>> items) async {
var max = 0;
for (final e in items) {
final s = (e['seq'] as num?)?.toInt() ?? 0;
if (s > max) max = s;
}
if (max > 0) await setLastSeq(conversationId, max);
}
}