2026-04-09 21:32:23 +08:00

572 lines
18 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
import 'package:yumi/app_localizations.dart';
import 'package:yumi/modules/index/main_route.dart';
import 'package:yumi/modules/store/store_route.dart';
import 'package:yumi/modules/user/settings/settings_route.dart';
import 'package:yumi/modules/wallet/wallet_route.dart';
import 'package:yumi/services/auth/user_profile_manager.dart';
import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
import 'package:yumi/ui_kit/components/sc_compontent.dart';
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
class MePage2 extends StatefulWidget {
const MePage2({super.key});
@override
State<MePage2> createState() => _MePage2State();
}
class _MePage2State extends State<MePage2> {
Map<String, SCUserCounterRes> _counterMap = {};
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_loadPageData();
});
}
void _loadPageData() {
final profileManager = Provider.of<SocialChatUserProfileManager>(
context,
listen: false,
);
profileManager.fetchUserProfileData();
profileManager.balance();
_loadCounter();
}
Future<void> _loadCounter() async {
final userId = AccountStorage().getCurrentUser()?.userProfile?.id ?? "";
if (userId.isEmpty) return;
try {
final userCounterList = await SCAccountRepository().userCounter(userId);
if (!mounted) return;
setState(() {
_counterMap = Map.fromEntries(
userCounterList.map(
(counter) => MapEntry(counter.counterType ?? "", counter),
),
);
});
} catch (_) {}
}
@override
Widget build(BuildContext context) {
return SafeArea(
top: true,
bottom: false,
child: Consumer<SocialChatUserProfileManager>(
builder: (context, profileManager, child) {
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.fromLTRB(10.w, 12.w, 10.w, 24.w),
child: Column(
children: [
_buildProfileSection(),
SizedBox(height: 12.w),
_buildStatsCard(),
SizedBox(height: 12.w),
_buildEntryRow(),
SizedBox(height: 12.w),
_buildWalletCard(),
SizedBox(height: 12.w),
_buildMenuCard2(),
SizedBox(height: 12.w),
_buildMenuCard([
_MenuRowData(
title: SCAppLocalizations.of(context)!.settings,
assetIcon: 'sc_images/index/sc_icon_settings.png',
onTap: () {
SCNavigatorUtils.push(
context,
SettingsRoute.settings,
replace: false,
);
},
),
_MenuRowData(
title: SCAppLocalizations.of(context)!.language,
assetIcon: 'sc_images/general/sc_icon_setting_language.png',
onTap: () {
SCNavigatorUtils.push(context, SCMainRoute.language);
},
),
]),
],
),
);
},
),
);
}
Widget _buildProfileSection() {
final profile = AccountStorage().getCurrentUser()?.userProfile;
return SCDebounceWidget(
onTap: () {
SCNavigatorUtils.push(
context,
'${SCMainRoute.person}?isMe=true&tageId=${profile?.id ?? ""}',
replace: false,
);
},
child: Column(
children: [
SizedBox(
width: 240.w,
height: 130.w,
child: Stack(
alignment: Alignment.topCenter,
children: [
head(
url: profile?.userAvatar ?? '',
width: 96.w,
height: 96.w,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 1),
headdress: profile?.getHeaddress()?.sourceUrl,
showDefault: true,
),
],
),
),
SizedBox(height: 8.w),
Text(
profile?.userNickname ?? '',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 2.w),
Text(
'ID:${profile?.account ?? ''}',
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.w600,
),
),
],
),
);
}
Widget _buildStatsCard() {
return _buildGlassCard(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.w),
radius: 8.w,
child: Row(
children: [
_buildStatItem(
value: _counterText('INTERVIEW'),
label: SCAppLocalizations.of(context)!.vistors,
onTap: () => SCNavigatorUtils.push(context, SCMainRoute.vistors),
),
_buildStatDivider(),
_buildStatItem(
value: _counterText('SUBSCRIPTION'),
label: SCAppLocalizations.of(context)!.following,
onTap: () => SCNavigatorUtils.push(context, SCMainRoute.follow),
),
_buildStatDivider(),
_buildStatItem(
value: _counterText('FANS'),
label: SCAppLocalizations.of(context)!.friends,
onTap: () => SCNavigatorUtils.push(context, SCMainRoute.fans),
),
],
),
);
}
Widget _buildEntryRow() {
return Row(
children: [
_buildEntryItem(
title: SCAppLocalizations.of(context)!.store,
iconPath: 'sc_images/index/sc_icon_shop.png',
onTap: () => SCNavigatorUtils.push(context, StoreRoute.list),
),
SizedBox(width: 10.w),
_buildEntryItem(
title: SCAppLocalizations.of(context)!.bag,
iconPath: 'sc_images/index/sc_icon_bag.png',
onTap: () => SCNavigatorUtils.push(context, StoreRoute.bags),
),
SizedBox(width: 10.w),
_buildEntryItem(
title: SCAppLocalizations.of(context)!.level,
iconPath: 'sc_images/index/sc_icon_level.png',
onTap: () => SCNavigatorUtils.push(context, SCMainRoute.levelList),
),
],
);
}
Widget _buildWalletCard() {
return SCDebounceWidget(
onTap: () => SCNavigatorUtils.push(context, WalletRoute.recharge),
child: Container(
width: double.infinity,
height: 90.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
image: const DecorationImage(
image: AssetImage('sc_images/index/sc_icon_wallet_bg.png'),
fit: BoxFit.fill,
),
),
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
SCAppLocalizations.of(context)!.wallet,
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.w800,
fontStyle: FontStyle.italic,
color: Colors.white,
),
),
SizedBox(height: 4.w),
Row(
children: [
Image.asset(
'sc_images/general/sc_icon_jb.png',
width: 28.w,
height: 28.w,
),
SizedBox(width: 6.w),
Consumer<SocialChatUserProfileManager>(
builder: (context, ref, child) {
return Text(
':${_balanceText(ref.myBalance)}',
style: TextStyle(
color: Colors.white,
fontSize: 24.sp,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
),
);
},
),
],
),
],
),
),
Image.asset(
'sc_images/index/sc_icon_wallet_icon.png',
width: 68.w,
height: 68.w,
),
],
),
),
);
}
Widget _buildMenuCard2() {
final userProfile = context.watch<SocialChatUserProfileManager>();
final items = <_MenuRowData>[];
// 1. 主播相关
if (userProfile.userIdentity?.anchor ?? false) {
if (userProfile.userIdentity?.agent ?? false) {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.agentCenter,
assetIcon: 'sc_images/index/at_icon_agent_center.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.agencyCenterUrl)}&showTitle=false",
);
},
),
);
} else {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.hostCenter,
assetIcon: 'sc_images/index/at_icon_host_center.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false",
);
},
),
);
}
}
// 2. BD 相关(非管理员时)
if (!(userProfile.userIdentity?.admin ?? false)) {
if (userProfile.userIdentity?.bdLeader ?? false) {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.bdLeader,
assetIcon: 'sc_images/index/at_icon_bd_leader.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdLeaderUrl)}&showTitle=false",
);
},
),
);
} else if (userProfile.userIdentity?.bd ?? false) {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.bdCenter,
assetIcon: 'sc_images/index/at_icon_bd_center.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdCenterUrl)}&showTitle=false",
);
},
),
);
}
}
// 3. 货运代理
if (userProfile.userIdentity?.freightAgent ?? false) {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.rechargeAgency,
assetIcon: 'sc_images/index/at_icon_recharge_agency.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false",
);
},
),
);
}
// 4. 管理员注意你的原逻辑中管理员和上面BD逻辑有重叠这里按原样单独处理
if (userProfile.userIdentity?.admin ?? false) {
items.add(
_MenuRowData(
title: SCAppLocalizations.of(context)!.adminCenter,
assetIcon: 'sc_images/index/at_icon_admin_center.png',
onTap: () {
SCNavigatorUtils.push(
context,
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.adminUrl)}&showTitle=false",
);
},
),
);
}
return _buildMenuCard(items);
}
Widget _buildMenuCard(List<_MenuRowData> items) {
// 没有任何项时,不显示整个卡片
if (items.isEmpty) return const SizedBox.shrink();
return _buildGlassCard(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.w),
radius: 4.w,
child: Column(
children: [
for (int i = 0; i < items.length; i++) ...[_buildMenuRow(items[i])],
],
),
);
}
Widget _buildMenuRow(_MenuRowData item) {
return SCDebounceWidget(
onTap: item.onTap,
child: SizedBox(
height: 46.w,
child: Row(
children: [
Image.asset(
item.assetIcon!,
width: 24.w,
height: 24.w,
color: Colors.white,
),
SizedBox(width: 12.w),
Expanded(
child: Text(
item.title,
style: TextStyle(
color: Colors.white,
fontSize: 15.sp,
fontWeight: FontWeight.w600,
),
),
),
Icon(
SCGlobalConfig.lang == 'ar'
? Icons.keyboard_arrow_left
: Icons.keyboard_arrow_right,
color: Colors.white,
size: 18.w,
),
],
),
),
);
}
Widget _buildEntryItem({
required String title,
required String iconPath,
required VoidCallback onTap,
}) {
return Expanded(
child: SCDebounceWidget(
onTap: onTap,
child: Container(
height: 110.w,
decoration: BoxDecoration(
image: const DecorationImage(
image: AssetImage('sc_images/person/sc_icon_me_menu_1_bg.png'),
fit: BoxFit.fill,
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(iconPath, width: 54.w, height: 54.w),
SizedBox(height: 4.w),
Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: 15.sp,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
);
}
Widget _buildStatItem({
required String value,
required String label,
required VoidCallback onTap,
}) {
return Expanded(
child: SCDebounceWidget(
onTap: onTap,
child: Column(
children: [
Text(
value,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 1.w),
Text(
label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
}
Widget _buildStatDivider() {
return Container(
width: 0.5.w,
height: 16.w,
color: const Color(0xFFE6E6E6).withOpacity(0.8),
margin: EdgeInsets.symmetric(horizontal: 6.w),
);
}
Widget _buildGlassCard({
required Widget child,
required EdgeInsets padding,
required double radius,
}) {
return Container(
width: double.infinity,
padding: padding,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(radius),
border: Border.all(color: const Color(0xFFB4FCCE), width: 1.w),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
const Color(0xFF0A7D49).withOpacity(0.20),
const Color(0xFF031513).withOpacity(0.35),
],
),
),
child: child,
);
}
String _counterText(String type) {
return _counterMap[type]?.quantity ?? '0';
}
String _balanceText(double balance) {
if (balance >= 1000) {
return '${(balance / 1000).toStringAsFixed(2)}k';
}
return balance.toStringAsFixed(balance % 1 == 0 ? 0 : 2);
}
}
class _MenuRowData {
const _MenuRowData({
required this.title,
required this.onTap,
this.assetIcon,
this.iconData,
});
final String title;
final String? assetIcon;
final IconData? iconData;
final VoidCallback onTap;
}