import 'package:flutter/material.dart'; import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; import '../services/im_service.dart'; import '../services/push_service.dart'; import '../theme.dart'; import '../widgets/avatar.dart'; import 'login_screen.dart'; /// 「我的」页:大头像 + 姓名 + 工号,设置 / 关于 / 退出登录 class MineScreen extends StatefulWidget { const MineScreen({super.key}); @override State createState() => _MineScreenState(); } class _MineScreenState extends State { @override void initState() { super.initState(); IMService.instance.refreshSelfInfo(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('我的')), body: AnimatedBuilder( animation: IMService.instance, builder: (context, _) { final user = IMService.instance.selfInfo; final nickname = user?.nickname?.isNotEmpty == true ? user!.nickname! : ''; final userID = IMService.instance.currentUserID ?? ''; return ListView( children: [ // 头部:大头像 + 姓名 + 工号 Container( color: AppColors.pageBg, padding: const EdgeInsets.all(AppGap.x4), child: Row( children: [ NameAvatar(name: nickname.isNotEmpty ? nickname : userID, faceURL: user?.faceURL, size: 64), const SizedBox(width: AppGap.x4), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( nickname.isNotEmpty ? nickname : userID, style: const TextStyle(fontSize: AppFont.title, fontWeight: FontWeight.w600, color: AppColors.textPrimary), ), const SizedBox(height: AppGap.x1), Text( '工号:$userID', style: const TextStyle(fontSize: AppFont.sub, color: AppColors.textSecondary), ), ], ), ], ), ), const SizedBox(height: AppGap.x3), _item(Icons.settings_outlined, '设置', () => _showSettings(nickname)), const Divider(indent: AppGap.x4), _item(Icons.info_outline, '关于', _showAbout), const Divider(indent: AppGap.x4), ListTile( leading: const Icon(Icons.logout, color: AppColors.danger), title: const Text('退出登录', style: TextStyle(fontSize: AppFont.body, color: AppColors.danger)), onTap: _confirmLogout, ), ], ); }, ), ); } Widget _item(IconData icon, String label, VoidCallback onTap) { return ListTile( leading: Icon(icon, color: AppColors.textPrimary), title: Text(label, style: const TextStyle(fontSize: AppFont.body)), trailing: const Icon(Icons.chevron_right, color: AppColors.textSecondary), onTap: onTap, ); } /// 设置:目前只有修改昵称 void _showSettings(String currentNickname) { final ctrl = TextEditingController(text: currentNickname); showModalBottomSheet( context: context, isScrollControlled: true, builder: (ctx) => Padding( padding: EdgeInsets.only( left: AppGap.x4, right: AppGap.x4, top: AppGap.x4, bottom: MediaQuery.of(ctx).viewInsets.bottom + AppGap.x4, ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text('修改昵称', style: TextStyle(fontSize: AppFont.title, fontWeight: FontWeight.w600)), const SizedBox(height: AppGap.x4), TextField( controller: ctrl, decoration: InputDecoration( hintText: '请输入新昵称', filled: true, fillColor: AppColors.searchBg, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none, ), ), ), const SizedBox(height: AppGap.x4), FilledButton( onPressed: () async { final name = ctrl.text.trim(); if (name.isEmpty) return; try { await OpenIM.iMManager.userManager.setSelfInfo(nickname: name); await IMService.instance.refreshSelfInfo(); if (ctx.mounted) Navigator.of(ctx).pop(); } catch (_) { if (ctx.mounted) { ScaffoldMessenger.of(ctx).showSnackBar( const SnackBar(content: Text('修改失败,请检查网络后重试'), duration: Duration(seconds: 2)), ); } } }, style: FilledButton.styleFrom(backgroundColor: AppColors.primary), child: const Text('保存', style: TextStyle(fontSize: AppFont.body)), ), ], ), ), ); } void _showAbout() { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('关于畅联'), content: const Text('畅联 1.0.0\n公司内部通讯工具,供同事之间消息、文件与语音通话使用。'), actions: [ TextButton(onPressed: () => Navigator.of(ctx).pop(), child: const Text('知道了')), ], ), ); } void _confirmLogout() { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('退出登录'), content: const Text('退出后要重新输入工号和密码,确定退出吗?'), actions: [ TextButton(onPressed: () => Navigator.of(ctx).pop(), child: const Text('取消')), TextButton( onPressed: () async { Navigator.of(ctx).pop(); await LoginScreen.clearCredential(); await PushService.instance.unbindUser(); await IMService.instance.logout(); if (!mounted) return; Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); }, child: const Text('退出', style: TextStyle(color: AppColors.danger)), ), ], ), ); } }