614 lines
19 KiB
Dart
614 lines
19 KiB
Dart
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 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",
|
||
);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
*/
|
||
|
||
// Debug: 临时注释原判断逻辑,固定展示三个入口,便于调试各自 WebView。
|
||
items.add(
|
||
_MenuRowData(
|
||
title: SCAppLocalizations.of(context)!.hostCenter,
|
||
assetIcon: 'sc_images/index/sc_icon_host_center.png',
|
||
onTap: () {
|
||
SCNavigatorUtils.push(
|
||
context,
|
||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false",
|
||
);
|
||
},
|
||
),
|
||
);
|
||
|
||
items.add(
|
||
_MenuRowData(
|
||
title: SCAppLocalizations.of(context)!.bdCenter,
|
||
assetIcon: 'sc_images/index/sc_icon_bd_center.png',
|
||
onTap: () {
|
||
SCNavigatorUtils.push(
|
||
context,
|
||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdCenterUrl)}&showTitle=false",
|
||
);
|
||
},
|
||
),
|
||
);
|
||
|
||
items.add(
|
||
_MenuRowData(
|
||
title: SCAppLocalizations.of(context)!.rechargeAgency,
|
||
assetIcon: 'sc_images/index/sc_icon_recharge_agency.png',
|
||
onTap: () {
|
||
SCNavigatorUtils.push(
|
||
context,
|
||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false",
|
||
);
|
||
},
|
||
),
|
||
);
|
||
|
||
// 4. 管理员(注意:你的原逻辑中管理员和上面BD逻辑有重叠,这里按原样单独处理)
|
||
final userProfile = context.watch<SocialChatUserProfileManager>();
|
||
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;
|
||
}
|