|
|
|
|
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<UserInfo> createState() => _UserInfoState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
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<MainTabView>().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: <Widget>[
|
|
|
|
|
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); // 更新头像路径到本地存储
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|