import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import '../../../data/models/goods.dart'; import '../../../data/models/user_Info.dart'; import '../controllers/goodsai_controller.dart'; class GoodsaiView extends GetView { const GoodsaiView({super.key}); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: AppBar( backgroundColor: isDarkMode ? Colors.black : Colors.white, elevation: 0.5, title: Text( 'aiFunction'.tr, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), centerTitle: true, ), body: Obx(() { // 访问刷新信号以建立依赖关系:用户信息变化时触发重建 final _ = User.refreshTick.value; if (controller.loading.value) { return const Center(child: CircularProgressIndicator()); } if (controller.error.isNotEmpty) { return Center(child: Text(controller.error.value)); } return ListView( padding: EdgeInsets.all(16.w), children: [ _buildHeader(isDarkMode), SizedBox(height: 12.h), _buildUsageCard(isDarkMode), SizedBox(height: 16.h), Text( '可购买套餐', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 8.h), ...controller.items.map((item) => Padding( padding: EdgeInsets.only(bottom: 12.h), child: _buildCard(item, isDarkMode), )), SizedBox(height: 16.h), _buildFeaturesSection(isDarkMode), SizedBox(height: 16.h), _buildFooterSection(isDarkMode), ], ); }), ); } Widget _buildHeader(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 44.w, height: 44.w, decoration: BoxDecoration( color: isDarkMode ? Colors.indigo[900]!.withOpacity(0.3) : Colors.indigo[100]!, borderRadius: BorderRadius.circular(22.r), ), child: Icon(Icons.smart_toy, color: isDarkMode ? Colors.indigo[300]! : Colors.indigo[600]!), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'AI 功能', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w700, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 6.h), Text( '更长对话额度、更多工具调用、更强上下文长度支持。', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[700], ), ), SizedBox(height: 4.h), Text( '适用于智能体问答、总结分析、任务执行等场景。', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[700], ), ), ], ), ), ], ), ); } Widget _buildUsageCard(bool isDarkMode) { // 从 User 属性计算 aitimer 数据 int totalAi = 0; int remainAi = 0; if (User.isLoggedIn()) { final u = User.instance; totalAi = u.aichattotalintegral; remainAi = u.aichatintegral; } // 进度显示为“剩余额度比例”,remain/total: final progress = (totalAi > 0) ? (remainAi / totalAi).clamp(0.0, 1.0) : 0.0; return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.timeline, color: isDarkMode ? Colors.blue[300]! : Colors.blue[600]!), SizedBox(width: 8.w), Text( '剩余额度', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 12.h), LinearProgressIndicator( value: progress, minHeight: 8.h, backgroundColor: isDarkMode ? Colors.grey[800] : Colors.grey[300], valueColor: AlwaysStoppedAnimation( isDarkMode ? Colors.blue[300]! : Colors.blue[600]!), ), SizedBox(height: 8.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '总次数:$totalAi', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[700], ), ), Text( '剩余:$remainAi', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[700], ), ), ], ), ], ), ); } Widget _buildFeaturesSection(bool isDarkMode) { final textColor = isDarkMode ? Colors.white : Colors.black; final subColor = isDarkMode ? Colors.white70 : Colors.grey[700]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '功能说明', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: textColor, ), ), SizedBox(height: 10.h), MasonryGridView.count( crossAxisCount: 2, mainAxisSpacing: 12.h, crossAxisSpacing: 12.w, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: 6, itemBuilder: (context, index) { switch (index) { case 0: return _buildFeatureCard( isDarkMode, icon: Icons.music_note, title: '听歌与推荐', lines: [ '检索曲库、播放控制', '智能推荐歌单与相似歌曲', ], colorSeed: Colors.purple, ); case 1: return _buildFeatureCard( isDarkMode, icon: Icons.navigation, title: '导航与路线', lines: [ '路线规划与拥堵规避', '语音播报与途径点设置', ], colorSeed: Colors.orange, ); case 2: return _buildFeatureCard( isDarkMode, icon: Icons.wb_sunny, title: '天气查询', lines: [ '实时天气与预报', '穿衣建议与出行提醒', ], colorSeed: Colors.blue, ); case 3: return _buildFeatureCard( isDarkMode, icon: Icons.place, title: '附近搜索', lines: [ '餐饮/加油/停车等地点检索', '评分、营业时间与路线直达', ], colorSeed: Colors.green, ); case 4: return _buildFeatureCard( isDarkMode, icon: Icons.newspaper, title: '新闻资讯', lines: [ '热点快讯与专题速览', '长文总结与要点提炼', ], colorSeed: Colors.indigo, ); default: return _buildFeatureCard( isDarkMode, icon: Icons.call, title: '通讯助手', lines: [ '帮忙拨打电话与发短信', '模板消息与日程提醒', ], colorSeed: Colors.teal, ); } }, ), SizedBox(height: 12.h), Text( '以上功能受设备权限、服务可用性与网络状况影响,具体以实际表现为准。', style: TextStyle(fontSize: 12.sp, color: subColor), ), ], ); } Widget _buildFooterSection(bool isDarkMode) { final subColor = isDarkMode ? Colors.white60 : Colors.grey[600]; return Padding( padding: EdgeInsets.symmetric(vertical: 12.h), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: double.infinity, child: Divider(color: isDarkMode ? Colors.white24 : Colors.black12), ), SizedBox(height: 8.h), Text( '应用名称:VoiTrans · 服务提供:VoiTrans', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), SizedBox(height: 4.h), Text( '更多信息请前往 设置 > 关于 查看', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), SizedBox(height: 4.h), Text( '© 2025 VoiTrans', textAlign: TextAlign.center, style: TextStyle(fontSize: 11.sp, color: subColor), ), ], ), ); } Widget _buildFeatureCard( bool isDarkMode, { required IconData icon, required String title, required List lines, required MaterialColor colorSeed, }) { final bgColor = isDarkMode ? Colors.grey[900] : Colors.white; final mainColor = isDarkMode ? colorSeed[300]! : colorSeed[600]!; final subColor = isDarkMode ? Colors.white70 : Colors.grey[700]; return Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 36.w, height: 36.w, decoration: BoxDecoration( color: isDarkMode ? mainColor.withOpacity(0.25) : mainColor.withOpacity(0.15), borderRadius: BorderRadius.circular(18.r), ), child: Icon(icon, color: mainColor), ), SizedBox(width: 8.w), Expanded( child: Text( title, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, ), ), ), ], ), SizedBox(height: 8.h), ...lines.map((line) => Padding( padding: EdgeInsets.only(bottom: 4.h), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Icons.check_circle, color: mainColor, size: 14.sp), SizedBox(width: 6.w), Expanded( child: Text( line, style: TextStyle(fontSize: 12.sp, color: subColor), ), ), ], ), )), ], ), ); } Widget _buildCard(DBGoods item, bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Row( children: [ Container( width: 42.w, height: 42.w, decoration: BoxDecoration( color: isDarkMode ? Colors.teal[900]!.withOpacity(0.3) : Colors.teal[100]!, borderRadius: BorderRadius.circular(21.r), ), child: Icon(Icons.auto_awesome, color: isDarkMode ? Colors.teal[300]! : Colors.teal[600]!), ), SizedBox(width: 12.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.name, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, )), SizedBox(height: 4.h), Text(item.desc, style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.grey[600], )), ], ), ), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text('¥${item.priceYuan.toStringAsFixed(2)}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, )), SizedBox(height: 8.h), GestureDetector( onTap: () => controller.purchase(item), child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h), decoration: BoxDecoration( color: Colors.blue[600], borderRadius: BorderRadius.circular(20.r), ), child: Text( '购买', style: TextStyle(fontSize: 12.sp, color: Colors.white), ), ), ), ], ), ], ), ); } }