From 4fb54e59a167171fad73fb4b8958470706153c56 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Thu, 24 Jul 2025 22:15:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=9A=E5=91=98=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting/views/meeting_mine_view.dart | 39 +- .../views/mine/meeting_member_view.dart | 531 +++++++++++++++++- 2 files changed, 547 insertions(+), 23 deletions(-) diff --git a/lib/modules/meeting/views/meeting_mine_view.dart b/lib/modules/meeting/views/meeting_mine_view.dart index 8c58f90aa..c2aa57307 100644 --- a/lib/modules/meeting/views/meeting_mine_view.dart +++ b/lib/modules/meeting/views/meeting_mine_view.dart @@ -371,28 +371,25 @@ class _MeetingMineViewState extends State fontSize: 12.sp, ), ), - GestureDetector( - onTap: () {}, - child: Container( - padding: EdgeInsets.symmetric( - horizontal: 10.w, - vertical: 6.w, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(50.w), - gradient: const LinearGradient( - colors: [Colors.blue, Colors.pink], - begin: Alignment.centerLeft, - end: Alignment.centerRight, - ), + Container( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 6.w, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50.w), + gradient: const LinearGradient( + colors: [Colors.blue, Colors.pink], + begin: Alignment.centerLeft, + end: Alignment.centerRight, ), - child: Text( - '立即解锁', - style: TextStyle( - color: Colors.white, - fontSize: 14.sp, - fontWeight: FontWeight.bold, - ), + ), + child: Text( + '立即解锁', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.bold, ), ), ), diff --git a/lib/modules/meeting/views/mine/meeting_member_view.dart b/lib/modules/meeting/views/mine/meeting_member_view.dart index 44e4328f3..b5caf7563 100644 --- a/lib/modules/meeting/views/mine/meeting_member_view.dart +++ b/lib/modules/meeting/views/mine/meeting_member_view.dart @@ -1,10 +1,537 @@ import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; -class MeetingMemberView extends StatelessWidget { +import '../../../profile/views/unified_avatar.dart'; +import '../../controllers/meeting_mine_controller.dart'; +import '../bottomSheet/member_bottom_sheet.dart'; + +class MeetingMemberView extends StatefulWidget { const MeetingMemberView({super.key}); + @override + State createState() => _MeetingMemberViewState(); +} + +class _MeetingMemberViewState extends State { + final _controller = Get.put(MeetingMineController()); + + int _tabsIndex = 0; + @override Widget build(BuildContext context) { - return const Placeholder(); + return Scaffold( + backgroundColor: Colors.black, + appBar: _buildAppBar(), + body: _buildBody(), + ); + } + + // 构建应用栏 + PreferredSizeWidget _buildAppBar() { + return AppBar( + backgroundColor: Colors.black, + surfaceTintColor: Colors.transparent, + elevation: 0.5, + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + color: Colors.white, + size: 20.sp, + ), + onPressed: () => Get.back(), + ), + title: Text( + 'VOITRANS AI会员', + style: TextStyle( + fontSize: 17.sp, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + centerTitle: true, + ); + } + + Widget _buildBody() { + return Container( + padding: EdgeInsets.symmetric(horizontal: 12.w), + child: ListView( + children: [ + _head(), + _member(), + _tabs(), + _comparison(), + ], + ), + ); + } + + Widget _head() { + return Padding( + padding: EdgeInsets.symmetric(vertical: 20.w), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 10.w), + child: UnifiedAvatar( + radius: 25.w, + backgroundColor: Colors.grey[200], + iconColor: Colors.grey[600], + iconSize: 25.r, + isDarkMode: true, + ), + ), + Expanded( + child: Obx( + () => Text( + _controller.profileCtrl.userInfo.value.name, + style: TextStyle( + color: Colors.white, + fontSize: 20.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ); + } + + Widget _member() { + return GestureDetector( + onTap: () { + Get.bottomSheet( + const MemberBottomSheet(), + isScrollControlled: true, + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12.r), + ), + ), + ); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 15.w), + decoration: BoxDecoration( + color: const Color(0xFF1A1A1A), + borderRadius: BorderRadius.circular(16.w), + ), + child: Column( + children: [ + Row( + children: [ + Icon( + Icons.auto_awesome, + color: Colors.amberAccent, + size: 25.sp, + ), + 5.horizontalSpace, + Text( + '解锁 Starter 会员', + style: TextStyle( + color: Colors.white, + fontSize: 18.sp, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + Padding( + padding: EdgeInsets.only(top: 15.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '绑定 Voitrans 设备可激活 Starter 会员', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + ), + ), + Container( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 6.w, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50.w), + gradient: const LinearGradient( + colors: [Colors.blue, Colors.pink], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: Text( + '立即解锁', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } + + Widget _tabs() { + return Container( + padding: EdgeInsets.all(2.w), + margin: EdgeInsets.only(top: 20.w, bottom: 5.w), + decoration: BoxDecoration( + color: Colors.grey[700], + borderRadius: BorderRadius.circular(10.w), + ), + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + _tabsIndex = 0; + }); + }, + behavior: HitTestBehavior.translucent, + child: Container( + height: 30.w, + alignment: Alignment.center, + decoration: _tabsIndex == 0 + ? BoxDecoration( + color: Colors.grey[50], + borderRadius: BorderRadius.circular(8.w), + ) + : null, + child: Text( + '对比', + style: TextStyle( + color: _tabsIndex == 0 ? Colors.black : Colors.white, + fontSize: 14.sp, + fontWeight: _tabsIndex == 0 ? FontWeight.bold : null, + ), + ), + ), + ), + ), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + _tabsIndex = 1; + }); + }, + behavior: HitTestBehavior.translucent, + child: Container( + height: 30.w, + alignment: Alignment.center, + decoration: _tabsIndex == 1 + ? BoxDecoration( + color: Colors.grey[50], + borderRadius: BorderRadius.circular(8.w), + ) + : null, + child: Text( + '详细信息', + style: TextStyle( + color: _tabsIndex == 1 ? Colors.black : Colors.white, + fontSize: 14.sp, + fontWeight: _tabsIndex == 1 ? FontWeight.bold : null, + ), + ), + ), + ), + ), + ], + ), + ); + } + + Widget _comparison() { + return Column( + children: [ + Container( + height: 50.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey[700]!, + width: 0.5, + ), + ), + ), + child: Row( + children: [ + const Expanded(child: SizedBox.square()), + Container( + width: 60.w, + alignment: Alignment.center, + child: Text( + 'Starter', + style: TextStyle( + color: Colors.grey[200], + fontSize: 14.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + width: 70.w, + alignment: Alignment.center, + child: Container( + width: 40.w, + height: 24.w, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.w), + gradient: const LinearGradient( + colors: [Colors.blue, Colors.pink], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: Text( + 'Pro', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + Container( + width: 72.w, + alignment: Alignment.center, + child: Container( + width: 72.w, + height: 24.w, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.w), + gradient: const LinearGradient( + colors: [ + Colors.amberAccent, + Colors.white, + Colors.amberAccent + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: Text( + 'Unlimited', + style: TextStyle( + color: Colors.black, + fontSize: 14.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ), + _tables( + '每月转写时长', + '300', + '1200', + '无限', + isGradient: true, + ), + _tables( + '专业模版', + '有限', + '全量模版', + '全量模版', + ), + _tables( + '专业术语', + '—', + '', + '', + ), + _tables( + '自定义模版', + '—', + '', + '', + ), + _tables( + 'Ask AI', + '—', + '', + '', + ), + _tables( + '可视化思维导图', + '', + '', + '', + ), + _tables( + '区分说话人', + '', + '', + '', + ), + _tables( + 'Private Cloud Sync', + '', + '', + '', + ), + _tables( + 'AI 人声增强', + '', + '', + '', + ), + _tables( + '音频导入', + '', + '', + '', + ), + _tables( + '支持多种导出格式', + '', + '', + '', + ), + ], + ); + } + + Widget _tables( + String title, + String starter, + String pro, + String unlimited, { + bool isGradient = false, + }) { + return Container( + height: 50.w, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey[700]!, + width: 0.5, + ), + ), + ), + child: Row( + children: [ + Expanded( + child: Text( + title, + style: TextStyle( + color: Colors.grey[200], + fontSize: 12.sp, + ), + ), + ), + Container( + width: 60.w, + alignment: Alignment.center, + child: starter.isNotEmpty + ? Text( + starter, + style: TextStyle( + color: Colors.grey[200], + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ) + : _check(false), + ), + Container( + width: 70.w, + alignment: Alignment.center, + child: pro.isNotEmpty + ? isGradient + ? ShaderMask( + shaderCallback: (bounds) => const LinearGradient( + colors: [Colors.blue, Colors.pink], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ).createShader(bounds), + child: Text( + pro, + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ), + ) + : Text( + pro, + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ) + : _check(isGradient), + ), + Container( + width: 72.w, + alignment: Alignment.center, + child: unlimited.isNotEmpty + ? ShaderMask( + shaderCallback: (bounds) => const LinearGradient( + colors: [ + Colors.amberAccent, + Colors.yellowAccent, + Colors.amberAccent, + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ).createShader(bounds), + child: Text( + unlimited, + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ), + ) + : _check(true), + ), + ], + ), + ); + } + + Widget _check(bool isGradient) { + return Container( + width: 20.w, + height: 20.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.grey[400], + borderRadius: BorderRadius.circular(20.w), + gradient: isGradient + ? const LinearGradient( + colors: [Colors.amberAccent, Colors.white, Colors.amberAccent], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ) + : null, + ), + child: Icon( + Icons.check, + color: Colors.black, + size: 16.sp, + ), + ); } }