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
+42
View File
@@ -0,0 +1,42 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/widgets.dart';
import '../session/session.dart';
/// 监听网络切换与应用恢复,触发 IM 极速重连。
class ImLifecycle with WidgetsBindingObserver {
ImLifecycle(this.session);
final SessionStore session;
StreamSubscription<List<ConnectivityResult>>? _netSub;
List<ConnectivityResult> _lastNet = const [];
void start() {
WidgetsBinding.instance.addObserver(this);
_netSub = Connectivity().onConnectivityChanged.listen(_onNet);
Connectivity().checkConnectivity().then((r) => _lastNet = r);
}
void stop() {
WidgetsBinding.instance.removeObserver(this);
_netSub?.cancel();
_netSub = null;
}
void _onNet(List<ConnectivityResult> next) {
final wasOffline = _lastNet.every((e) => e == ConnectivityResult.none);
final nowOnline = next.any((e) => e != ConnectivityResult.none);
_lastNet = next;
if (wasOffline && nowOnline && session.signedIn) {
unawaited(session.connectIm(force: true));
}
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed && session.signedIn) {
unawaited(session.connectIm(force: true));
}
}
}