import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; import '../../api/api_client.dart'; import '../../api/api_client_info.dart'; import '../../common_widget/app_data.dart'; import '../../view_model/home_view_model.dart'; import '../../view/main_tab_view/main_tab_view.dart'; class UserInfo extends StatefulWidget { const UserInfo({super.key}); @override State createState() => _UserInfoState(); } class _UserInfoState extends State { final listVM = Get.put(HomeViewModel()); final TextEditingController _controller = TextEditingController(); File? _selectedImage; @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage("assets/img/app_bg.png"), fit: BoxFit.cover, ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( centerTitle: true, backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( onPressed: () { // 返回到 MainTabView 并切换到“个人”标签页 Get.back(); // 关闭当前页面并返回到主界面 // 等待页面关闭后再切换标签 Future.delayed(Duration(milliseconds: 100), () { // 查找 MainTabView 并获取 TabController final mainTabController = Get.find().getController(context); if (mainTabController != null) { mainTabController.index = 3; // 切换到“个人”标签页的索引 } }); }, icon: Image.asset( "assets/img/back.png", width: 25, height: 25, fit: BoxFit.contain, ), ), title: const Text( "账户信息", style: TextStyle( color: Colors.black, fontSize: 25, fontWeight: FontWeight.w400), ), ), body: SingleChildScrollView( child: Column( children: [ _buildAvatarRow(), _buildNicknameRow(), ], ), ), ), ); } // 构建头像行 Widget _buildAvatarRow() { return Container( height: 80, color: Colors.white.withOpacity(0.6), padding: const EdgeInsets.only(left: 48, right: 25), child: InkWell( onTap: () { _bottomSheet(context); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( "头像", style: TextStyle(fontSize: 20), ), Row( children: [ _buildAvatarImage(), const SizedBox(width: 20), Image.asset( "assets/img/user_next.png", width: 25, height: 25, ), ], ), ], ), ), ); } // 构建昵称行 Widget _buildNicknameRow() { return Container( height: 80, color: Colors.white.withOpacity(0.6), padding: const EdgeInsets.only(left: 48, right: 25), child: InkWell( onTap: () { _showNicknameDialog(); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( "昵称", style: TextStyle(fontSize: 20), ), Row( children: [ Text( AppData().currentUsername, style: const TextStyle(fontSize: 20), ), const SizedBox(width: 15), Image.asset( "assets/img/user_next.png", width: 25, height: 25, ), ], ), ], ), ), ); } // 显示头像的 Widget,根据是否是网络 URL 或本地路径来动态加载 Widget _buildAvatarImage() { final avatarPath = AppData().currentAvatar; if (avatarPath.startsWith('http')) { return Image.network( avatarPath, width: 64, height: 64, ); } else { return Image.file( File(avatarPath), width: 64, height: 64, ); } } Future _bottomSheet(BuildContext context) async { final picker = ImagePicker(); await showModalBottomSheet( context: context, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(30))), builder: (context) => Container( height: 132, padding: const EdgeInsets.only(top: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ ElevatedButton( onPressed: () async { Navigator.pop(context); final pickedFile = await picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { _selectedImage = File(pickedFile.path); setState(() {}); // 更新 UI // 上传头像 await ChangeApiClient().changeHeader( Authorization: AppData().currentToken, avatar: _selectedImage!); // 更新本地存储 _updatetouxiang(_selectedImage!.path); // 拉取更新后的用户信息 await GetInfoApiClient().getInfo( Authorization: AppData().currentToken); } }, style: ElevatedButton.styleFrom( backgroundColor: Colors.transparent, elevation: 0, padding: const EdgeInsets.symmetric(vertical: 12), tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: const Text( "从相册上传头像", style: TextStyle(color: Colors.black, fontSize: 18), ), ), ElevatedButton( onPressed: () => Navigator.pop(context), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xff429482), padding: const EdgeInsets.symmetric(vertical: 18), tapTargetSize: MaterialTapTargetSize.shrinkWrap, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.zero, ), ), child: const Text( "取消", style: TextStyle(color: Colors.black, fontSize: 18), ), ), ], ), ), ); } void _showNicknameDialog() { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Center( child: Text( "修改昵称", style: TextStyle(fontSize: 20), )), content: TextField( controller: _controller, decoration: const InputDecoration(hintText: '请输入新昵称'), ), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "取消", style: TextStyle(color: Colors.white), ), ), TextButton( onPressed: () async { _updateNickname(); await ChangeApiClient().changeName( Authorization: AppData().currentToken, userName: AppData().currentUsername); Navigator.of(context).pop(); }, style: TextButton.styleFrom( backgroundColor: const Color(0xff429482), minimumSize: const Size(130, 50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), ), child: const Text( "保存", style: TextStyle(color: Colors.white), ), ), ], ); }, ); } void _updateNickname() { setState(() { AppData appData = AppData(); appData.box.write('currentUsername', _controller.text); }); } void _updatetouxiang(String path) { setState(() { AppData appData = AppData(); appData.box.write('currentAvatar', path); // 更新头像路径到本地存储 }); } }