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,103 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import 'api/oa_client.dart';
|
||||
import 'app_runtime.dart';
|
||||
import 'device/device_bridge.dart';
|
||||
import 'desktop/desk_platform.dart';
|
||||
import 'desktop/desk_theme.dart';
|
||||
import 'pages/desktop_login_page.dart';
|
||||
import 'pages/login_page.dart';
|
||||
import 'session/session.dart';
|
||||
import 'shell/home_shell.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await AppRuntime.load();
|
||||
if (isDesktopPlatform) {
|
||||
await windowManager.ensureInitialized();
|
||||
const windowOptions = WindowOptions(
|
||||
size: Size(1400, 900),
|
||||
center: true,
|
||||
title: '风影办公',
|
||||
);
|
||||
windowManager.waitUntilReadyToShow(windowOptions, () async {
|
||||
await windowManager.show();
|
||||
await windowManager.focus();
|
||||
});
|
||||
}
|
||||
if (!isDesktopPlatform) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.white,
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
));
|
||||
DeviceBridge.preferMaxRefresh();
|
||||
}
|
||||
runApp(const FengyingApp());
|
||||
}
|
||||
|
||||
class FengyingApp extends StatefulWidget {
|
||||
const FengyingApp({super.key});
|
||||
|
||||
@override
|
||||
State<FengyingApp> createState() => _FengyingAppState();
|
||||
}
|
||||
|
||||
class _FengyingAppState extends State<FengyingApp> {
|
||||
final session = SessionStore();
|
||||
late final OaClient api = OaClient(session);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
DeviceBridge.bindApi(api);
|
||||
session.addListener(_onSession);
|
||||
_boot();
|
||||
}
|
||||
|
||||
Future<void> _boot() async {
|
||||
await session.load();
|
||||
if (session.signedIn) {
|
||||
try {
|
||||
final me = await api.get('/auth/me');
|
||||
if (me is Map) {
|
||||
await session.patchUser(Map<String, dynamic>.from(me));
|
||||
}
|
||||
final menus = await api.get('/system/menus');
|
||||
await session.setMenus(asMaps(menus).map(MenuNode.fromJson).toList());
|
||||
await session.connectIm();
|
||||
} catch (_) {
|
||||
await session.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _onSession() => setState(() {});
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
session.removeListener(_onSession);
|
||||
session.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: '风影办公',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: isDesktopPlatform ? buildDesktopTheme() : buildTheme(),
|
||||
home: !session.loaded
|
||||
? const Scaffold(backgroundColor: Colors.white, body: Center(child: CircularProgressIndicator(color: kBind)))
|
||||
: session.signedIn
|
||||
? HomeShell(session: session, api: api)
|
||||
: isDesktopPlatform
|
||||
? DesktopLoginPage(session: session, api: api)
|
||||
: LoginPage(session: session, api: api),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user