diff --git a/circle_app/assets/images/circle/share_more.png b/circle_app/assets/images/circle/share_more.png new file mode 100644 index 0000000..b60ea37 Binary files /dev/null and b/circle_app/assets/images/circle/share_more.png differ diff --git a/circle_app/assets/images/mine/bi_icon1.png b/circle_app/assets/images/mine/bi_icon1.png new file mode 100644 index 0000000..3cfc788 Binary files /dev/null and b/circle_app/assets/images/mine/bi_icon1.png differ diff --git a/circle_app/assets/images/mine/bi_icon2.png b/circle_app/assets/images/mine/bi_icon2.png new file mode 100644 index 0000000..dbe5537 Binary files /dev/null and b/circle_app/assets/images/mine/bi_icon2.png differ diff --git a/circle_app/assets/images/mine/bi_icon3.png b/circle_app/assets/images/mine/bi_icon3.png new file mode 100644 index 0000000..50370f1 Binary files /dev/null and b/circle_app/assets/images/mine/bi_icon3.png differ diff --git a/circle_app/assets/images/mine/bi_icon4.png b/circle_app/assets/images/mine/bi_icon4.png new file mode 100644 index 0000000..cae2479 Binary files /dev/null and b/circle_app/assets/images/mine/bi_icon4.png differ diff --git a/circle_app/assets/images/mine/chevron_left.png b/circle_app/assets/images/mine/chevron_left.png new file mode 100644 index 0000000..e840643 Binary files /dev/null and b/circle_app/assets/images/mine/chevron_left.png differ diff --git a/circle_app/assets/images/mine/gift_no_data.png b/circle_app/assets/images/mine/gift_no_data.png new file mode 100644 index 0000000..e5ec3a0 Binary files /dev/null and b/circle_app/assets/images/mine/gift_no_data.png differ diff --git a/circle_app/assets/images/mine/gift_no_data_bg.png b/circle_app/assets/images/mine/gift_no_data_bg.png new file mode 100644 index 0000000..100b1bf Binary files /dev/null and b/circle_app/assets/images/mine/gift_no_data_bg.png differ diff --git a/circle_app/assets/images/mine/gift_shop_icon.png b/circle_app/assets/images/mine/gift_shop_icon.png new file mode 100644 index 0000000..efabbdf Binary files /dev/null and b/circle_app/assets/images/mine/gift_shop_icon.png differ diff --git a/circle_app/assets/images/mine/gift_top_star.png b/circle_app/assets/images/mine/gift_top_star.png new file mode 100644 index 0000000..dbb7765 Binary files /dev/null and b/circle_app/assets/images/mine/gift_top_star.png differ diff --git a/circle_app/assets/images/mine/icon_pay_select.png b/circle_app/assets/images/mine/icon_pay_select.png index bd89593..d253a42 100644 Binary files a/circle_app/assets/images/mine/icon_pay_select.png and b/circle_app/assets/images/mine/icon_pay_select.png differ diff --git a/circle_app/assets/images/mine/im_ky_bc.png b/circle_app/assets/images/mine/im_ky_bc.png new file mode 100644 index 0000000..806e275 Binary files /dev/null and b/circle_app/assets/images/mine/im_ky_bc.png differ diff --git a/circle_app/assets/images/mine/un_check_icon.png b/circle_app/assets/images/mine/un_check_icon.png new file mode 100644 index 0000000..aae1478 Binary files /dev/null and b/circle_app/assets/images/mine/un_check_icon.png differ diff --git a/circle_app/assets/images/mine/wallet.png b/circle_app/assets/images/mine/wallet.png new file mode 100644 index 0000000..e17f92c Binary files /dev/null and b/circle_app/assets/images/mine/wallet.png differ diff --git a/circle_app/assets/images/mine/wen.png b/circle_app/assets/images/mine/wen.png new file mode 100644 index 0000000..98a9991 Binary files /dev/null and b/circle_app/assets/images/mine/wen.png differ diff --git a/circle_app/assets/images/msg/gift.png b/circle_app/assets/images/msg/gift.png new file mode 100644 index 0000000..b9024f2 Binary files /dev/null and b/circle_app/assets/images/msg/gift.png differ diff --git a/circle_app/assets/images/msg/gift_bg.png b/circle_app/assets/images/msg/gift_bg.png new file mode 100644 index 0000000..5f4ac5a Binary files /dev/null and b/circle_app/assets/images/msg/gift_bg.png differ diff --git a/circle_app/assets/images/msg/vip_month.png b/circle_app/assets/images/msg/vip_month.png new file mode 100644 index 0000000..8295c83 Binary files /dev/null and b/circle_app/assets/images/msg/vip_month.png differ diff --git a/circle_app/assets/images/msg/vip_quarter.png b/circle_app/assets/images/msg/vip_quarter.png new file mode 100644 index 0000000..f768bf4 Binary files /dev/null and b/circle_app/assets/images/msg/vip_quarter.png differ diff --git a/circle_app/assets/images/msg/vip_year.png b/circle_app/assets/images/msg/vip_year.png new file mode 100644 index 0000000..33031f2 Binary files /dev/null and b/circle_app/assets/images/msg/vip_year.png differ diff --git a/circle_app/lib/app/bill/binding.dart b/circle_app/lib/app/bill/binding.dart new file mode 100644 index 0000000..c5f2d2d --- /dev/null +++ b/circle_app/lib/app/bill/binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'logic.dart'; + +class BillBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => BillLogic()); + } +} diff --git a/circle_app/lib/app/bill/logic.dart b/circle_app/lib/app/bill/logic.dart new file mode 100644 index 0000000..c77e41f --- /dev/null +++ b/circle_app/lib/app/bill/logic.dart @@ -0,0 +1,146 @@ +import 'dart:convert'; + +import 'package:get/get.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; + +import '../../network/api.dart'; +import 'state.dart'; + +class BillLogic extends GetxController { + final BillState state = BillState(); + final int rechargePage = 1; + List rechargeList=[]; + final RefreshController rechargeController = RefreshController(); + + final int consumePage = 1; + List consumeList=[]; + final RefreshController consumeController = RefreshController(); + + final int incomePage = 1; + List incomeList=[]; + final RefreshController incomeController = RefreshController(); + + final int withdrawalPage = 1; + List withdrawalList=[]; + final RefreshController withdrawalController = RefreshController(); + + @override + void onInit() async { + super.onInit(); + getBillList(1,1); + getBillList(2,1); + getBillList(3,1); + } + + getBillList(int type, int page) async { + var data = await DioManager.getInstance().post(url: Api.userBill, params: { + "type": type, + "page": page, + "pageSize": 20, + }); + + if (data['code'] == 200) { + BillResponse billResponse = BillResponse.fromJson(data); + RefreshController? controller; + switch (type) { + case 1: + if (page == 1) { + rechargeList.clear(); + } + controller = rechargeController; + rechargeList.addAll(billResponse.list); + if (rechargeList.length < 10) { + controller!.loadNoData(); + } + break; + case 2: + if (page == 1) + consumeList.clear(); + controller = consumeController; + consumeList.addAll(billResponse.list); + if (consumeList.length < 10) { + controller!.loadNoData(); + } + break; + case 3: + if (page == 1) + incomeList.clear(); + controller = incomeController; + incomeList.addAll(billResponse.list); + if (incomeList.length < 10) { + controller!.loadNoData(); + } + break; + case 4: + if (page == 1) + withdrawalList.clear(); + controller = withdrawalController; + withdrawalList.addAll(billResponse.list); + if (withdrawalList.length < 10) { + controller!.loadNoData(); + } + break; + } + + + if (page == 1) { + controller!.refreshCompleted(); + } else { + controller!.loadComplete(); + } + + update(); + } + } + + + +} + +class BillResponse { + int code; + String msg; + int total; + List list; + + BillResponse({ + required this.code, + required this.msg, + required this.total, + required this.list, + }); + + factory BillResponse.fromJson(Map json) { + return BillResponse( + code: json['code'], + msg: json['msg'], + total: json['data']['total'], + list: List.from( + json['data']['lists'].map((item) => BillItem.fromJson(item))), + ); + } +} + +class BillItem { + int billId; + String billDate; + String billName; + double amount; + + BillItem({ + required this.billId, + required this.billDate, + required this.billName, + required this.amount, + }); + + factory BillItem.fromJson(Map json) { + return BillItem( + billId: json['billId'], + billDate: json['billDate'], + billName: json['billName'], + amount: json['amount']?.toDouble() ?? 0.0, + ); + } +} diff --git a/circle_app/lib/app/bill/state.dart b/circle_app/lib/app/bill/state.dart new file mode 100644 index 0000000..ade6f54 --- /dev/null +++ b/circle_app/lib/app/bill/state.dart @@ -0,0 +1,5 @@ +class BillState { + BillState() { + ///Initialize variables + } +} diff --git a/circle_app/lib/app/bill/view.dart b/circle_app/lib/app/bill/view.dart new file mode 100644 index 0000000..1a934ca --- /dev/null +++ b/circle_app/lib/app/bill/view.dart @@ -0,0 +1,280 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; + +import '../../util/util.dart'; +import 'logic.dart'; + +class BillPage extends StatefulWidget { + BillPage({Key? key}) : super(key: key); + + @override + _BillState createState() => _BillState(); +} + +class _BillState extends State with SingleTickerProviderStateMixin { + final logic = Get.find(); + final state = Get.find().state; + + late TabController _tabController; + late PageController _pageController; + + ScrollController scrollController = ScrollController(); + bool isShowBlackTitle = false; + + @override + void initState() { + super.initState(); + _pageController = PageController(); + _tabController = TabController(length: 3, vsync: this,initialIndex: Get.arguments ?? 0); + _tabController.animation!.addListener(_handleTabChange); + // _tabController.addListener(_handleTabChange); + // _tabController + } + + void _handleTabChange() { + // 在这里可以执行滑动监听后的逻辑操作 + // 比如根据当前选中的标签执行其他操作 + // int currentIndex = .toString()); + // logic.isShowAlbum = _tabController.index == 0; + // logic.update(); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + // _getFormat(context); + return GetBuilder(builder: (logic) { + return Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(getBaseImage("bg")), + fit: BoxFit.cover, + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + // appBar: MyAppBar(centerTitle: '账单',), + body: SafeArea( + child: Container( + margin: EdgeInsets.only(top: 13.sp), + child: Stack( + children: [ + Positioned( + left: 18.sp, + child: GestureDetector( + onTap: (){ + Get.back(); + }, + child: Image.asset( + "assets/images/navigator/back.png", + width: 24.sp, + height: 24.sp, + ), + )), + Column( + children: [ + titleTab(logic), + Expanded( + child: TabBarView( + controller: _tabController, + // onPageChanged: (index) { + // _tabController.animateTo(index); + // }, + children: [ + billListView(1), + billListView(2), + billListView(3), + // billListView(4), + ], + ), + ), + ], + ) + ], + ), + ), + ), + ), + ); + }); + } + Widget billListView(int type){ + List list= []; + int page = 0; + RefreshController? controller; + + switch(type){ + case 1: + page = logic.rechargePage; + controller = logic.rechargeController; + list = logic.rechargeList; + break; + case 2: + page = logic.consumePage; + controller = logic.consumeController; + list = logic.consumeList; + break; + case 3: + page = logic.incomePage; + controller = logic.incomeController; + list = logic.incomeList; + break; + case 4: + page = logic.withdrawalPage; + controller = logic.withdrawalController; + list = logic.withdrawalList; + break; + } + + return list.isNotEmpty ? Container( + margin: EdgeInsets.only(top: 22.sp), + child: SmartRefresher( + controller: controller!, + onRefresh: () => onRefresh(type, page), + onLoading: () => onLoading(type, page), + enablePullUp: true, + child: ListView.builder( + itemCount: list.length, + // Replace 'yourList' with the actual list you want to display + itemBuilder: (context, index) { + return ListItemWidget(item: list[index],type: type,); + }, + ), + ), + ) : noResultWidget(); + } + + + onRefresh(int type,int page) async { + logic.getBillList(type, page); + // logic.page = 1; + // logic.initList(); + } + + onLoading(int type,int page) async { + page = page+1; + logic.getBillList(type, page); + // logic.page = logic.page + 1; + // logic.initList(); + } + + Widget titleTab(BillLogic controller) { + return Container( + alignment: Alignment.centerLeft, + // padding: EdgeInsets.symmetric(horizontal: 10.sp), + height: 30.sp, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TabBar( + isScrollable: true, + controller: _tabController, + indicator: UnderlineTabIndicator( + borderSide: BorderSide( + color: const Color(0xFFCE51FF), + + ), + insets: EdgeInsets.symmetric(horizontal: 6.0.sp), + // borderRadius: BorderRadius.circular(18.0), + ), + indicatorColor: const Color(0xFFCE51FF), + indicatorWeight: 2.sp, + labelColor: const Color(0xFFCE51FF), + unselectedLabelColor: const Color(0xB3FFFFFF), + indicatorSize: TabBarIndicatorSize.label, + labelStyle: TextStyle(fontSize: 16.sp), + tabs: const [ + Tab( + text: "充值", + ), + Tab(text: "消耗"), + Tab(text: "收入"), + ], + onTap: (index) { + // _pageController.animateToPage( + // index, // 目标页面索引 + // duration: const Duration(milliseconds: 300), // 动画时长 + // curve: Curves.ease, // 动画曲线 + // ); + }, + + ), + ], + ), + ); + } +} + +class ListItemWidget extends StatelessWidget { + final BillItem item; + final int type; + ListItemWidget({required this.item , required this.type}); + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.only(left: 16.0, bottom: 16.0,right: 16.sp), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + getMineImage("bi_icon1"), + // Assuming you have the image in the 'assets/images/' directory + width: 24.sp, + height: 24.sp, + ), + SizedBox(width: 8.0.sp), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.billName, + style: TextStyle( + color: Color(0xfff7fafa), + fontSize: 14.0.sp, + ), + ), + SizedBox(height: 4.0.sp), + Text( + item.billDate, + style: TextStyle( + color: Color(0xffb7becc), + fontSize: 12.0.sp, + ), + ), + ], + ), + Spacer(), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + type==2 ? '-'+item.amount.toString(): '+'+item.amount.toString(), + style: TextStyle( + color: const Color(0xffefd84e), + fontSize: 14.0.sp, + ), + ), + ], + ), + ], + ), + SizedBox(height: 8.0.sp), + Divider( + height: 10.0.sp, + color: Colors.white.withOpacity(0.3.sp), + ), + ], + ), + ); + } +} diff --git a/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart index ffa66d1..2f6848a 100644 --- a/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart +++ b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart @@ -1,8 +1,10 @@ import 'dart:convert'; import 'dart:math'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:circle_app/app/chat/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart'; import 'package:circle_app/app/chat/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem.dart'; +import 'package:circle_app/app/chat/widget/chat_msg_partner_item.dart'; import 'package:circle_app/router/app_routers.dart'; import 'package:circle_app/util/util.dart'; import 'package:flutter/cupertino.dart'; @@ -42,6 +44,9 @@ import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import '../../../../common/Widgets/text_more.dart'; +import '../../../circle/logic.dart'; +import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_chat_gift_elem.dart'; import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; typedef MessageRowBuilder = Widget? Function( @@ -400,6 +405,30 @@ class _TIMUIKItHistoryMessageListItemState () => model.jumpMsgID = "", )!; } + // sendVip + + + if (messageItem.customElem?.data?.contains('giftImageUrl') ?? false) { + return GiftElem( + chatModel: model, + message: messageItem, + isFromSelf: messageItem.isSelf ?? true, + clearJump: clearJump, + isShowJump: isShowJump, + borderRadius: widget.themeData?.messageBorderRadius, + fontStyle: widget.themeData?.messageTextStyle, + backgroundColor: widget.themeData?.messageBackgroundColor, + textPadding: widget.textPadding, + isShowMessageReaction: widget.isUseMessageReaction, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, + ); + } + + if (messageItem.customElem?.extension?.contains('sendVip') ?? false) { + return ChatMsgPartnerItem(messageItem); + } + if (messageItem.customElem?.extension?.contains('cardData') ?? false) { Map info = jsonDecode(messageItem.customElem?.data ?? ''); return Column( @@ -553,6 +582,24 @@ class _TIMUIKItHistoryMessageListItemState ) ], ); + } else if (messageItem.customElem?.extension?.contains('circleData') ?? false) { + Map info = jsonDecode(messageItem.customElem?.data ?? ''); + var bean = Circle.fromJson(info); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: Get.width, + child: Container( + width: Get.width, + margin: EdgeInsets.only(left: isFromSelf ? 16 : 0,right: isFromSelf ? 0 : 16), + alignment: Alignment.center, + child: circleInfoItem(bean), + + ), + ) + ], + ); } return TIMUIKitCustomElem( @@ -739,6 +786,241 @@ class _TIMUIKItHistoryMessageListItemState } } + circleWidget(String url, String userId, {double width = 24}) { + return Stack( + alignment: Alignment.center, + children: [ + Image.asset( + getCircleImage('avatar_bg'), + width: width.sp, + ), + ClipOval( + child: CachedNetworkImage( + imageUrl: url ?? + "https://qiniuyun.leyuan666.com/quanzi/avatar/default.png", + width: (width - 1).sp, + height: (width - 1).sp, + fit: BoxFit.cover, + memCacheHeight: width.toInt() - 1, + memCacheWidth: width.toInt() - 1, + ), + ) + ], + ); + } + + circleInfoItem(Circle bean) { + List urlList = bean.lastJoinUsers; + List widgets = []; + int i = 0; + // print(urlList); + if (null != urlList) { + urlList.forEach((element) { + if (widgets.length > 2) { + return; + } + widgets.add(Positioned( + left: 15.sp * i, + child: circleWidget( + element.avatar! ?? + "https://qiniuyun.leyuan666.com/quanzi/avatar/default.png", + element.id.toString()), + )); + i++; + }); + } + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.sp), + gradient: LinearGradient(colors: [Color(0xFF261240),Color(0xFF132C40),]) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.sp), + topRight: Radius.circular(10.sp)), + child: Container( + padding: EdgeInsets.only(left: 12.sp, right: 12.sp), + height: 72.sp, + width: Get.width - 30.sp, + decoration: BoxDecoration( + + image: DecorationImage( + fit: BoxFit.fill, + image: AssetImage(getCircleImage('top_circle_bg'))), + + ), + child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 42.sp, + height: 42.sp, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + gradient: const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0xFF71F3F2), + Color(0xFFF558FF), + ], + stops: [0.0365, 0.9427], + ), + ), + padding: EdgeInsets.all(1.sp), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.0), + child: CachedNetworkImage( + imageUrl: bean.image, + width: 40.sp, + height: 40.sp, + memCacheHeight: 40, + memCacheWidth: 40, + fit: BoxFit.cover), + ), + ), + Expanded( + child: Container( + padding: EdgeInsets.only(left: 8.sp, top: 12.sp), + // alignment: Alignment., + height: 72.sp, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + bean.title, + style: TextStyle( + color: Colors.white, + fontSize: 18.sp, + fontWeight: FontWeight.w600), + ), + SizedBox( + height: 4.sp, + ), + Text( + '${convertToTenThousand(bean.viewTotal)}人看过', + textAlign: TextAlign.left, + style: TextStyle( + color: const Color(0xff03FEFB), + fontSize: 12.sp, + ), + ), + ], + ), + )), + + GestureDetector( + onTap: () { + Get.toNamed(AppRoutes.Signal_circle_list, arguments: bean.id); + }, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset( + getCircleImage('add'), + width: 77.sp, + ), + Text( + '查看圈子', + style: TextStyle( + color: Colors.white, fontSize: 12.sp), + ) + ], + ), + ) + ], + ), + )), + Container( + padding: EdgeInsets.only(left: 12.sp, right: 12.sp), + // height:urlList.length==0?47.sp: 118.sp, + decoration: BoxDecoration( + image: DecorationImage( + fit: BoxFit.fill, + image: AssetImage(getCircleImage('circle_desc'))) + ), + child: Container( + margin: EdgeInsets.only(top: 10.sp, bottom: 10.sp), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(bottom: 7.sp), + width: Get.width - 20.sp - 32, + // height: 50.sp, + child: HideText( + text: bean.intro, + maxWidth: Get.width - 84.sp, + additionText: '查看更多', + maxLines: 3, + style: TextStyle(color: Colors.white, fontSize: 14.sp), + additionStyle: TextStyle( + color: const Color(0xFFFF4DF6), fontSize: 14.sp), + onTap: () { + + }, + )), + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + // showToast("点个鸡毛,星哥还没做"); + // Get.toNamed(AppRoutes.FriendsActivity,arguments: '3'); + }, + child: urlList.length == 0 + ? Container() + : Row( + children: [ + SizedBox( + height: 30.sp, + width: + 30.0.sp + 14.sp * (widgets.length - 1.sp), + child: Stack( + alignment: Alignment.center, + children: widgets, + ), + ), + SizedBox( + width: 4.sp, + ), + Text( + '${convertToTenThousand(bean.joinTotal)}圈友加入', + style: TextStyle( + color: Colors.white, fontSize: 12.sp), + ), + SizedBox( + width: 4.sp, + ), + // GestureDetector( + // onTap: () { + // Get.bottomSheet( + // CircleShare('code','link,',bean), isScrollControlled: true, + // enableDrag: false + // ); + // }, + // behavior: HitTestBehavior.opaque, + // child: Container( + // height: 30.sp, + // alignment: Alignment.center, + // child: Image.asset( + // getCircleImage('play'), + // width: 20.sp, + // ), + // ), + // ) + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + interestWdiget(List data) { if (!data.isNotEmpty) return Container(height: 0,); return Container( @@ -1451,7 +1733,8 @@ class _TIMUIKItHistoryMessageListItemState } }, child: (message.customElem?.extension?.contains('cardData') ?? - false) + false) || (message.customElem?.extension?.contains('circleData') ?? + false) ? _getMessageItemBuilder(message, 1, model) : Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -1670,8 +1953,7 @@ class _TIMUIKItHistoryMessageListItemState ), ), if (isSelf && - widget.showAvatar && - message.elemType != 2) + widget.showAvatar) widget.userAvatarBuilder != null ? widget.userAvatarBuilder!(context, message) : SizedBox( diff --git a/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_chat_gift_elem.dart b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_chat_gift_elem.dart new file mode 100644 index 0000000..4724d67 --- /dev/null +++ b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_chat_gift_elem.dart @@ -0,0 +1,372 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_extended_text/extended_text.dart'; +import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/link_preview_entry.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/widgets/link_preview.dart'; + +import '../../../widget/chat_gift_pannel.dart'; + +class GiftElem extends StatefulWidget { + final V2TimMessage message; + final bool isFromSelf; + final bool isShowJump; + final VoidCallback clearJump; + final TextStyle? fontStyle; + final BorderRadius? borderRadius; + final Color? backgroundColor; + final EdgeInsetsGeometry? textPadding; + final TUIChatSeparateViewModel chatModel; + final bool? isShowMessageReaction; + final bool isUseDefaultEmoji; + final List customEmojiStickerList; + + const GiftElem( + {Key? key, + required this.message, + required this.isFromSelf, + required this.isShowJump, + required this.clearJump, + this.fontStyle, + this.borderRadius, + this.isShowMessageReaction, + this.backgroundColor, + this.textPadding, + required this.chatModel, + this.isUseDefaultEmoji = false, + this.customEmojiStickerList = const []}) + : super(key: key); + + @override + State createState() => _GiftElemState(); +} + +class _GiftElemState extends TIMUIKitState { + bool isShowJumpState = false; + bool isShining = false; + + @override + void initState() { + super.initState(); + // get the link preview info + _getLinkPreview(); + } + + @override + void didUpdateWidget(var oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.message.msgID == null && widget.message.msgID != null) { + _getLinkPreview(); + } + } + + _showJumpColor() { + if ((widget.chatModel.jumpMsgID != widget.message.msgID) && + (widget.message.msgID?.isNotEmpty ?? true)) { + return; + } + isShining = true; + int shineAmount = 6; + setState(() { + isShowJumpState = true; + }); + Timer.periodic(const Duration(milliseconds: 300), (timer) { + if (mounted) { + setState(() { + isShowJumpState = shineAmount.isOdd ? true : false; + }); + } + if (shineAmount == 0 || !mounted) { + isShining = false; + timer.cancel(); + } + shineAmount--; + }); + Future.delayed(const Duration(milliseconds: 100), () { + widget.clearJump(); + }); + } + + // get the link preview info + _getLinkPreview() { + if (widget.chatModel.chatConfig.urlPreviewType != + UrlPreviewType.previewCardAndHyperlink) { + return; + } + try { + if (widget.message.localCustomData != null && + widget.message.localCustomData!.isNotEmpty) { + final String localJSON = widget.message.localCustomData!; + final LocalCustomDataModel? localPreviewInfo = + LocalCustomDataModel.fromMap(json.decode(localJSON)); + // If [localCustomData] is not empty, check if the link preview info exists + if (localPreviewInfo == null || localPreviewInfo.isLinkPreviewEmpty()) { + // If not exists, get it + _initLinkPreview(); + } + } else { + // It [localCustomData] is empty, get the link info + _initLinkPreview(); + } + } catch (e) { + return null; + } + } + + _initLinkPreview() async { + // Get the link preview info from extension, let it update the message UI automatically by providing a [onUpdateMessage]. + // The `onUpdateMessage` can use the `updateMessage()` from the [TIMUIKitChatController] directly. + LinkPreviewEntry.getFirstLinkPreviewContent( + message: widget.message, + onUpdateMessage: (message) { + widget.chatModel.updateMessageFromController( + msgID: widget.message.msgID!, message: message); + }); + } + + Widget? _renderPreviewWidget() { + // If the link preview info from [localCustomData] is available, use it to render the preview card. + // Otherwise, it will returns null. + if (widget.message.localCustomData != null && + widget.message.localCustomData!.isNotEmpty) { + try { + final String localJSON = widget.message.localCustomData!; + final LocalCustomDataModel? localPreviewInfo = + LocalCustomDataModel.fromMap(json.decode(localJSON)); + if (localPreviewInfo != null && + !localPreviewInfo.isLinkPreviewEmpty()) { + return Container( + margin: const EdgeInsets.only(top: 8), + child: + // You can use this default widget [LinkPreviewWidget] to render preview card, or you can use custom widget. + LinkPreviewWidget(linkPreview: localPreviewInfo), + ); + } else { + return null; + } + } catch (e) { + return null; + } + } else { + return null; + } + } + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final textWithLink = LinkPreviewEntry.getHyperlinksText( + widget.message.textElem?.text ?? "", + widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, + onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, + isEnableTextSelection: + widget.chatModel.chatConfig.isEnableTextSelection); + final borderRadius = widget.isFromSelf + ? const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(10), + bottomRight: Radius.circular(2)) + : const BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10), + bottomLeft: Radius.circular(2), + bottomRight: Radius.circular(10)); + if ((widget.chatModel.jumpMsgID == widget.message.msgID)) {} + if (widget.isShowJump) { + if (!isShining) { + Future.delayed(Duration.zero, () { + _showJumpColor(); + }); + } else { + if ((widget.chatModel.jumpMsgID == widget.message.msgID) && + (widget.message.msgID?.isNotEmpty ?? false)) { + widget.clearJump(); + } + } + } + + final defaultStyle = widget.isFromSelf + ? (theme.chatMessageItemFromSelfBgColor ?? + theme.lightPrimaryMaterialColor.shade50) + : (theme.chatMessageItemFromOthersBgColor); + + final backgroundColor = isShowJumpState + ? const Color.fromRGBO(245, 166, 35, 1) + : (defaultStyle ?? widget.backgroundColor); + + if (!widget.isFromSelf) { + return Container( + // decoration: BoxDecoration( + // gradient: + // LinearGradient(colors: [Color(0xFF04FCFB), Color(0xFFE540FE)]), + // // color: backgroundColor, + // borderRadius: widget.borderRadius ?? borderRadius, + // ), + child: Container( + margin: EdgeInsets.all(1), + // padding: + // widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 11 : 9), + // decoration: BoxDecoration( + // color: const Color(0xFF493E5C), + // // color: backgroundColor, + // borderRadius: widget.borderRadius ?? borderRadius, + // ), + constraints: + BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ChatMsgGiftItem(widget.message, widget.isFromSelf), + GestureDetector( + onTap: () { + showGiftPannel(widget.message); + }, + child: Container( + height: 30.sp, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.sp), + gradient: AppColor.mainVerLinearGradient, + ), + child: Text( + '给TA回个礼,让感情升升温', + style: TextStyle(color: Colors.white), + ), + ), + ) + ], + ), + ), + ); + } + + return Container( + // padding: + // widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), + decoration: BoxDecoration( + gradient: + LinearGradient(colors: [Color(0xFF04FCFB), Color(0xFFE540FE)]), + // color: backgroundColor, + borderRadius: widget.borderRadius ?? borderRadius, + ), + constraints: + BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ChatMsgGiftItem(widget.message, widget.isFromSelf)], + ), + ); + } +} + +class ChatMsgGiftItem extends StatelessWidget { + final V2TimMessage message; + bool isMe; + // TODO: add state variables, methods and constructor params + ChatMsgGiftItem(this.message, this.isMe); + + @override + Widget build(BuildContext context) { + Map giftData = jsonDecode(message.customElem!.data!); + + // "msg" -> "{\"giftImageUrl\":\"http://qiniuyun.ikuayou.com/live/gifts/2.png\",\"giftName\":\"舔狗楷模\",\"gmtNotice\":\"2023-0..." + // TODO: add widget build method + return Container( + width: MediaQuery.of(context).size.width * 0.6, + color: isMe ? Colors.transparent : Colors.transparent, + child: Stack( + alignment: Alignment.center, + children: [ + if (!isMe) + Container( + height: 78.sp, + // padding: + // widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [Color(0xFF04FCFB), Color(0xFFE540FE)]), + // color: backgroundColor, + borderRadius: BorderRadius.circular(8.sp), + ), + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.6), + ), + Container( + height: 76.sp, + margin: EdgeInsets.all(1.sp), + decoration: BoxDecoration( + color: isMe ? Colors.transparent : Color(0xFF493E5C), + borderRadius: BorderRadius.circular(8.sp)), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 10.sp), + child: CachedNetworkImage( + imageUrl: giftData['giftImageUrl'], + width: 60.sp, + height: 60.sp, + )), + Expanded( + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + // color: Colors.red, + // alignment: Alignment.center, + child: Text( + (!isMe ? '送出' : '送你') + + '${giftData['num']}个${giftData['giftName']}', + style: TextStyle( + color: Color(0xFFF7FAFA), fontSize: 14.sp), + overflow: TextOverflow.ellipsis, + ), + ), + SizedBox( + height: 8.sp, + ), + Container( + child: Text( + '价值${giftData['totalPrice']}小票', + style: TextStyle( + color: Color(0xFFF7FAFA), fontSize: 14.sp), + overflow: TextOverflow.ellipsis, + ), + ) + ], + ), + ), + ), + ], + ), + ), + ], + ), + ); + } +} + +showGiftPannel(var message) { + Get.bottomSheet( + ChatGiftPannel(accid: message.sender!), + isScrollControlled: false, + enableDrag: false, + ); +} diff --git a/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart index d7299b2..407b144 100644 --- a/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart +++ b/circle_app/lib/app/chat/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart @@ -38,6 +38,7 @@ import 'package:video_thumbnail/video_thumbnail.dart'; import '../../../../../util/eventBus.dart'; import '../../../../call_out/logic.dart'; +import '../../../widget/chat_gift_pannel.dart'; GlobalKey<_TIMTextFieldLayoutNarrowState> TIMnarrowTextFieldKey = GlobalKey(); @@ -412,6 +413,16 @@ class _TIMTextFieldLayoutNarrowState return Container(); } + showGiftPannel() { + Get.bottomSheet( + ChatGiftPannel( + accid: widget.conversationID, + ), + isScrollControlled: false, + enableDrag: false, + ); + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; @@ -474,61 +485,104 @@ class _TIMTextFieldLayoutNarrowState constraints: const BoxConstraints(minHeight: 30), child: Row( children: [ - if (widget.forbiddenText != null) - Expanded( - child: Container( - height: 35, - color: theme.weakBackgroundColor, - alignment: Alignment.center, - child: Text( - TIM_t(widget.forbiddenText!), - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - color: theme.weakTextColor, - ), - ), - )), - if (PlatformUtils().isMobile && - widget.showSendAudio && - widget.forbiddenText == null) - InkWell( - onTap: () async { - showKeyboard = showSendSoundText; - if (showSendSoundText) { - widget.focusNode.requestFocus(); - } - if (await Permissions.checkPermission( - context, - Permission.microphone.value, - theme, - )) { + // if (widget.forbiddenText != null) + // Expanded( + // child: Container( + // height: 35, + // color: theme.weakBackgroundColor, + // alignment: Alignment.center, + // child: Text( + // TIM_t(widget.forbiddenText!), + // textAlign: TextAlign.center, + // style: TextStyle( + // fontWeight: FontWeight.bold, + // fontSize: 16, + // color: theme.weakTextColor, + // ), + // ), + // )), + // if (PlatformUtils().isMobile && + // widget.showSendAudio && + // widget.forbiddenText == null) + // InkWell( + // onTap: () async { + // showKeyboard = showSendSoundText; + // if (showSendSoundText) { + // widget.focusNode.requestFocus(); + // } + // if (await Permissions.checkPermission( + // context, + // Permission.microphone.value, + // theme, + // )) { + // setState(() { + // showEmojiPanel = false; + // showMore = false; + // showSendSoundText = !showSendSoundText; + // }); + // } + // }, + // child: SvgPicture.asset( + // showSendSoundText + // ? 'images/keyboard.svg' + // : 'images/voice.svg', + // package: 'tencent_cloud_chat_uikit', + // color: const Color.fromRGBO(68, 68, 68, 1), + // height: 28, + // width: 28, + // ), + // ), + // if (widget.forbiddenText == null) + // const SizedBox( + // width: 10, + // ), + GestureDetector( + onTap: () async { + if (isBlack) { + showOKToast("您已将对方拉黑,请移除黑名单后在发送消息~"); + return; + } + showKeyboard = showSendSoundText; + if (showSendSoundText) { + widget.focusNode.requestFocus(); + } + try { + var data = await Permission.microphone.status; + if (data.isGranted) { setState(() { showEmojiPanel = false; showMore = false; showSendSoundText = !showSendSoundText; }); + } else { + var data = + await Permission.microphone.request(); + if (data.isGranted) { + setState(() { + showEmojiPanel = false; + showMore = false; + showSendSoundText = !showSendSoundText; + }); + } else { + Permissions.showPermissionConfirmDialog( + context, Permission.microphone.value); + } } - }, - child: SvgPicture.asset( - showSendSoundText - ? 'images/keyboard.svg' - : 'images/voice.svg', - package: 'tencent_cloud_chat_uikit', - color: const Color.fromRGBO(68, 68, 68, 1), - height: 28, - width: 28, - ), - ), - if (widget.forbiddenText == null) - const SizedBox( - width: 10, + } catch (e) { + print(e); + } + }, + child: Image.asset( + getMsgImage('voice'), + width: 25.sp, ), + ), + SizedBox(width: 10.sp,), Stack( children: [ Container( - width: Get.width - 80.sp, + width: Get.width - 95.sp, + // width: 296.sp, padding: EdgeInsets.symmetric( vertical: 8, horizontal: 12.sp), @@ -540,6 +594,7 @@ class _TIMTextFieldLayoutNarrowState ), child: Row( children: [ + if (widget.forbiddenText == null) Expanded( child: showSendSoundText @@ -648,7 +703,8 @@ class _TIMTextFieldLayoutNarrowState ), ), ], - )) + )), + ], ), if (widget.forbiddenText == null) @@ -683,47 +739,7 @@ class _TIMTextFieldLayoutNarrowState child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - GestureDetector( - onTap: () async { - if (isBlack) { - showOKToast("您已将对方拉黑,请移除黑名单后在发送消息~"); - return; - } - showKeyboard = showSendSoundText; - if (showSendSoundText) { - widget.focusNode.requestFocus(); - } - try { - var data = await Permission.microphone.status; - if (data.isGranted) { - setState(() { - showEmojiPanel = false; - showMore = false; - showSendSoundText = !showSendSoundText; - }); - } else { - var data = - await Permission.microphone.request(); - if (data.isGranted) { - setState(() { - showEmojiPanel = false; - showMore = false; - showSendSoundText = !showSendSoundText; - }); - } else { - Permissions.showPermissionConfirmDialog( - context, Permission.microphone.value); - } - } - } catch (e) { - print(e); - } - }, - child: Image.asset( - getMsgImage('voice'), - width: 40.sp, - ), - ), + GestureDetector( onTap: () { if (isBlack) { @@ -746,6 +762,19 @@ class _TIMTextFieldLayoutNarrowState child: Image.asset(getMsgImage('take_photo'), width: 40.sp), ), + GestureDetector( + onTap: () async { + if (isBlack) { + showOKToast("您已将对方拉黑,请移除黑名单后在发送消息~"); + return; + } + showGiftPannel(); + }, + child: Image.asset( + getMsgImage('gift'), + width: 40.sp, + ), + ), GestureDetector( onTap: () { if (isBlack) { diff --git a/circle_app/lib/app/chat/view.dart b/circle_app/lib/app/chat/view.dart index b98f803..34c14bc 100644 --- a/circle_app/lib/app/chat/view.dart +++ b/circle_app/lib/app/chat/view.dart @@ -168,7 +168,7 @@ class _ChatPageState extends State { ], ), customAppBar:MyAppBar( - centerTitle: con.showName! ?? '', + centerTitle: con.showName != null ? con.showName! : '', actionWdiget: GestureDetector( onTap: () async{ var data = await Get.toNamed(AppRoutes.UserInfoActivity,arguments: con.userID.toString().split('_').last,preventDuplicates: false); diff --git a/circle_app/lib/app/chat/widget/chat_gift_pannel.dart b/circle_app/lib/app/chat/widget/chat_gift_pannel.dart new file mode 100644 index 0000000..72851ad --- /dev/null +++ b/circle_app/lib/app/chat/widget/chat_gift_pannel.dart @@ -0,0 +1,173 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:circle_app/components/func_widget.dart'; +import 'package:circle_app/network/api.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:circle_app/router/app_routers.dart'; +import 'package:circle_app/util/util.dart'; + +import 'gift.dart'; +import 'partner_option.dart'; + +class ChatGiftPannel extends StatefulWidget { + String accid; + int selectedIndex; + ChatGiftPannel({Key? key,required this.accid,this.selectedIndex = 0}) : super(key: key); + + @override + State createState() => _ChatGiftPannelState(); +} + +class _ChatGiftPannelState extends State + with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { + late TabController tabController; + + + @override + // TODO: implement wantKeepAlive + bool get wantKeepAlive => true; + + void initState() { + // TODO: implement initState + tabController = TabController( + length:2, + vsync: this, + initialIndex: widget.selectedIndex + ); + tabController.addListener(() { + setState(() { + + }); + }); + super.initState(); + // getPropMall(); + // getAsset(); + } + + + + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + backgroundColor: Colors.transparent, + body: Container( + width: Get.width, + height: Get.height, + child: Column( + children: [ + Expanded(child: Container()), + Container( + // color: Color(0xFF423055), + child: SafeArea( + top: false, + child: Container( + decoration: BoxDecoration( + color: Color(0xFF423055), + borderRadius: BorderRadius.only(topLeft: Radius.circular(16.sp,),topRight: Radius.circular(16.sp)) + ), + width: Get.width, + height: 370.sp, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: 30.sp, + width:120.sp, + margin: EdgeInsets.only(left: 5.sp,), + child: TabBar( + isScrollable: false, + automaticIndicatorColorAdjustment: false, + labelPadding: EdgeInsets.symmetric(horizontal: 4.0.sp), + physics: NeverScrollableScrollPhysics(), + indicatorColor: AppColor.mainColor, + indicatorSize: TabBarIndicatorSize.label, + unselectedLabelStyle: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + ), + unselectedLabelColor: Color(0xB3FFFFFF), + labelColor: AppColor.mainColor, + labelStyle: TextStyle( + fontSize: 14.sp, fontWeight: FontWeight.w500), + controller: tabController, + tabs: const [ + Tab( + text: '礼物', + ), + Tab( + text: '会员', + ), + ], + ), + ), + tabController.index == 0 ? Container( + margin: EdgeInsets.only(right: 15.sp), + child: InkWell( + onTap: () { + String toUserId = widget.accid!.split('_').last; + Get.toNamed(AppRoutes.GiftShopPage,arguments: toUserId); + }, + child: Container( + height:22.sp, + width: 62.sp, + decoration: BoxDecoration( + gradient: AppColor.mainVerLinearGradient, + borderRadius: BorderRadius.circular(11.sp) + ), + child: Stack( + alignment: Alignment.center, + children: [ + Container( + height:20.sp, + width: 60.sp, + decoration: BoxDecoration( + color: Color(0xFF423055), + borderRadius: BorderRadius.circular(10.sp) + )), + Text('礼物馆',style: TextStyle(color: Colors.white,fontSize: 14.sp),) + ], + ), + )), + ) : Container() + ], + ), + Expanded( + child: TabBarView( + controller: tabController, + children: [ + Gift(widget.accid,), + PartnerOption(accid: widget.accid), + ], + )) + ], + ), + ))) + ], + ), + ), + ); + } + + // void _showCustomDialog( + // BuildContext context, int id, List priceCombo) { + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return BuyPropDialog( + // id: id, + // priceCombo: priceCombo, + // ); + // }, + // ); + // } + + + +} diff --git a/circle_app/lib/app/chat/widget/chat_msg_gift_item.dart b/circle_app/lib/app/chat/widget/chat_msg_gift_item.dart new file mode 100644 index 0000000..bce12d9 --- /dev/null +++ b/circle_app/lib/app/chat/widget/chat_msg_gift_item.dart @@ -0,0 +1,90 @@ +import 'dart:convert'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/app/chat/widget/chat_gift_pannel.dart'; + +class ChatMsgGiftItem extends StatelessWidget { + var message; + // TODO: add state variables, methods and constructor params + ChatMsgGiftItem(this.message); + + @override + Widget build(BuildContext context) { + + Map data = message.messageAttachment!.toMap(); + Map giftData = jsonDecode(data['data']['msg']); + bool isMe = message.sessionId == message.fromAccount; + // "msg" -> "{\"giftImageUrl\":\"http://qiniuyun.ikuayou.com/live/gifts/2.png\",\"giftName\":\"舔狗楷模\",\"gmtNotice\":\"2023-0..." + // TODO: add widget build method + return Container( + width: 203.sp, + color: Colors.black87, + child: Column( + children: [ + Container( + height: 80.sp, + decoration: BoxDecoration( + color: Color(0xFF292836), + borderRadius: BorderRadius.circular(8.sp) + ), + child: Row( + children: [ + Container(margin: EdgeInsets.only(left: 10.sp),child: CachedNetworkImage(imageUrl: giftData['giftImageUrl'],width: 60.sp,height: 60.sp,)), + Expanded( + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + // color: Colors.red, + // alignment: Alignment.center, + child: Text((!isMe ? '送出' : '送你') + '${giftData['num']}个${giftData['giftName']}',style: TextStyle(color: Color(0xFFF7FAFA),fontSize: 14.sp),overflow: TextOverflow.ellipsis,), + ), + SizedBox(height: 8.sp,), + Container( + child: Text('价值${giftData['totalPrice']}豆子',style: TextStyle(color: Color(0xFFF7FAFA),fontSize: 14.sp),overflow: TextOverflow.ellipsis,), + ) + ], + ), + ), + ) + ], + ), + ), + !isMe ? Container() : GestureDetector( + onTap: () { + showGiftPannel(); + }, + child: Container( + height: 30.sp, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.sp), + gradient: const LinearGradient( + colors: [ + Color(0xFF9457FE), + Color(0xFFCF4CFF), + ], + ), + ), + child: Text('给TA回个礼,让感情升升温',style: TextStyle(color: Colors.white),), + ), + ) + ], + ), + ); + } + + + showGiftPannel() { + Get.bottomSheet( + ChatGiftPannel(accid:message.sessionId!.toString(),), + isScrollControlled: false, + enableDrag: false, + ); + } + +} diff --git a/circle_app/lib/app/chat/widget/chat_msg_partner_item.dart b/circle_app/lib/app/chat/widget/chat_msg_partner_item.dart new file mode 100644 index 0000000..b253698 --- /dev/null +++ b/circle_app/lib/app/chat/widget/chat_msg_partner_item.dart @@ -0,0 +1,139 @@ +import 'dart:convert'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/app/chat/widget/chat_gift_pannel.dart'; +import 'package:circle_app/util/util.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; + +class ChatMsgPartnerItem extends StatelessWidget { + V2TimMessage message; + // TODO: add state variables, methods and constructor params + ChatMsgPartnerItem(this.message); + // TODO: add state variables, methods and constructor params + List vipTitleName = [ + 365, + 90, + 30, + ]; + + List vipName = [ + "vip_year", + "vip_quarter", + "vip_month", + ]; + + @override + Widget build(BuildContext context) { + // TODO: add widget build method + // Map data = message.messageAttachment!.toMap(); + Map giftData = jsonDecode(message.customElem!.data!); + bool isMe = message.isSelf!; + int price = giftData['totalPrice']; + + int index = 0; + if (giftData['num'] == 90) { + index = 1; + } else if (giftData['num'] == 30) { + index = 2; + } + // TODO: add widget build method + return Container( + width: Get.width * 0.6, + child: Column( + children: [ + Container( + height: 78.sp, + decoration: BoxDecoration( + gradient: isMe + ? AppColor.mainVerLinearGradient + : const LinearGradient( + colors: [ + Color(0xFF493E5C), + Color(0xFF493E5C), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + // color: Color(0xFF493E5C), + borderRadius: BorderRadius.circular(8.sp)), + child: Row( + children: [ + // "propImageUrl" -> "https://qiniuyun.ikuayou.com/2023/xhPHUJ.png""monthNum" -> 3 + Container( + margin: EdgeInsets.only(left: 10.sp), + child: Image.asset( + getMsgImage(vipName[index]), + width: 60.sp, + height: 60.sp, + )), + Expanded( + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + // color: Colors.red, + // alignment: Alignment.center, + child: Text( + (isMe ? '送出' : '送你') + '${giftData['giftName']}', + style: TextStyle( + color: Color(0xFFF7FAFA), fontSize: 14.sp), + overflow: TextOverflow.ellipsis, + ), + ), + SizedBox( + height: 8.sp, + ), + Container( + child: Text( + '价值${price.toInt()}元', + style: TextStyle( + color: Color(0xFFF7FAFA), fontSize: 14.sp), + overflow: TextOverflow.ellipsis, + ), + ) + ], + ), + ), + ) + ], + ), + ), + isMe + ? Container() + : GestureDetector( + onTap: () { + showGiftPannel(); + }, + child: Container( + height: 30.sp, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.sp), + gradient: AppColor.mainVerLinearGradient), + child: Text( + '给TA回个礼,让感情升升温', + style: TextStyle(color: Colors.white), + ), + ), + ) + ], + ), + ); + } + + showGiftPannel() { + Get.bottomSheet( + ChatGiftPannel( + accid: message.sender!, + selectedIndex: 1, + ), + isScrollControlled: false, + enableDrag: false, + ); + } +} diff --git a/circle_app/lib/app/chat/widget/gift.dart b/circle_app/lib/app/chat/widget/gift.dart new file mode 100644 index 0000000..111c05a --- /dev/null +++ b/circle_app/lib/app/chat/widget/gift.dart @@ -0,0 +1,359 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:circle_app/components/func_widget.dart'; +import 'package:circle_app/network/api.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:circle_app/util/util.dart'; + +import '../../../common/Widgets/base_tip_widget.dart'; + +class Gift extends StatefulWidget { + String accid; + Gift(this.accid, {super.key}); + @override + _GiftState createState() => _GiftState(); +} + +class _GiftState extends State { + var livePlatform = MethodChannel('com.flutter.liveView'); + List giftList = []; + + String giftId = ''; + + String tipStr = ''; + + String incomeBalance = ''; + + int giftCount = 1; + + int selectedIndex = -1; + + bool isShowCount = false; + + @override + void initState() { + // TODO: implement initState + super.initState(); + loadGiftData(); + getAsset(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + color: Colors.transparent, + child: Column( + children: [ + + widget.accid!.isNotEmpty ? Container( + margin: EdgeInsets.only(top: 10.sp, bottom: 10.sp), + width: Get.width, + alignment: Alignment.center, + child: Text( + tipStr.isNotEmpty ? '礼物送出后,获得$tipStr小时的消息置顶' : '', + style: TextStyle( + color: AppColor.mainColor, + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + ) : Container(), + Expanded( + child: Container( + width: Get.width, + child: ListView.builder( + itemCount: giftList.length, + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return giftGridWidget(giftList[index]); + }), + )), + Container( + padding: EdgeInsets.only(left: 16.sp, right: 16.sp), + height: 48.sp, + width: Get.width, + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 4.sp), + child: Image.asset( + getMineImage('bi_icon1'), + width: 24.sp, + ), + ), + Text( + '${incomeBalance}', + style: TextStyle( + color: Color(0xFFF7FAFA), + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + SizedBox( + width: 16.sp, + ), + GestureDetector( + onTap: () { + showRechargeScreenDialog().then((value) { + getAsset(); + }); + }, + child: Text( + '充值>', + style: TextStyle( + color: AppColor.mainColor, + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + ), + Expanded(child: Container()), + GestureDetector( + onTap: () { + isShowCount = !isShowCount; + setState(() {}); + }, + child: Container( + height: 27.sp, + decoration: BoxDecoration( + color: Color(0xFF3E3D4C), + borderRadius: BorderRadius.circular(13.5.sp)), + child: Row( + children: [ + SizedBox( + width: 18.sp, + ), + Text( + '${giftCount}', + style: TextStyle( + color: Color(0xFFF7FAFA), + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + SizedBox( + width: 10.sp, + ), + const Icon( + Icons.arrow_drop_down, + color: Colors.white, + size: 20, + ), + SizedBox( + width: 8.sp, + ), + GestureDetector( + onTap: () { + if (giftId.isEmpty) { + showOKToast('请选择您想赠送的礼物'); + } else { + sendGiftData(); + } + }, + child: Container( + width: 56.sp, + height: 27.sp, + decoration: BoxDecoration( + gradient: AppColor.mainVerLinearGradient, + borderRadius: BorderRadius.circular(13.5.sp)), + alignment: Alignment.center, + child: Text( + '赠送', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + ), + ) + ], + ), + ), + ) + ], + ), + ) + ], + ), + ), + isShowCount + ? Positioned(bottom: 45.sp, right: 15.sp, child: giftCountWidget()) + : Container() + ], + ); + } + + + void sendGiftData() async { + var result = await DioManager.instance.post(url: Api.sendGift,params: {'accid':widget.accid,'giftId':giftId,'num':giftCount,'toUserId':widget.accid!.split('_').last}); + if (result['code'] == 200) { + showOKToast('赠送成功'); + getAsset(); + } else if (result['code'] == 31201) { + showOKToast(result['msg']); + showRechargeScreenDialog().then((value) => getAsset()); + } + } + + + void loadGiftData() async { + var result = await DioManager.instance.get(url: Api.giftList); + if (result['code'] == 200) { + List dataList = result['data']; + List giftItemData = []; + for (int i = 0; i < dataList.length; i++) { + giftItemData.add(dataList[i]); + if (i % 7 == 0 && i != 0) { + List temp = []; + temp.addAll(giftItemData); + giftList.add(temp); + giftItemData.clear(); + } + } + setState(() {}); + } + } + + getAsset() async { + var jsonMap = await DioManager.getInstance().get(url: Api.userAsset); + + if (jsonMap['code'] == 200) { + incomeBalance = jsonMap['data']['balance'].toString(); + + setState(() {}); + } + } + + giftGridWidget(List info) { + return Container( + width: Get.width, + height: 245.sp, + padding: EdgeInsets.only(left: 16.sp, right: 16.sp), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 8.0.sp, + mainAxisSpacing: 8.0.sp, + childAspectRatio: 0.7, + ), + itemCount: info.length, + // Replace with the actual item count + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + // Replace the placeholders with the actual item widgets + return giftItemWidget(info[index],index); + }, + ), + ); + } + + giftItemWidget(Map info,int index) { + bool isSelected = giftId.contains(info['id'].toString()); + double price = info['price']; + + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + selectedIndex = index; + giftId = info['id'].toString(); + tipStr = info['topHours'] != null ? info['topHours'].toString() : ''; + setState(() {}); + }, + child: Container( + height: 105.sp, + // decoration: BoxDecoration( + // image: DecorationImage( + // image: AssetImage(getMsgImage('gift_bg'),), + // ) + // // color: isSelected ? Color(0xFF3E3D4C) : Colors.transparent, + // // borderRadius: BorderRadius.circular(4.sp), + // // border: Border.all( + // // color: isSelected ? AppColor.mainColor : Colors.transparent, + // // width: isSelected ? 1.sp : 0.0) + // ), + child: Stack( + fit: StackFit.expand, + children: [ + isSelected ? Image.asset(getMsgImage('gift_bg')) : Container(), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.network( + info['icon'], + width: 48.sp, + height: 48.sp, + ), + Text(info['name'], + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w500)), + Text('${price.toInt()}小票', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w500)) + ], + ) + ], + ), + ), + ); + } + + giftCountWidget() { + return Container( + decoration: BoxDecoration( + color: Color(0xFF3E3D4C), borderRadius: BorderRadius.circular(8.sp)), + child: Column( + children: [ + giftCountItemWidget(1314, '一生一世', () {}), + giftCountItemWidget(520, '我爱你', () {}), + giftCountItemWidget(299, '爱久久', () {}), + giftCountItemWidget(66, '六六大顺', () {}), + giftCountItemWidget(10, '十全十美', () {}), + giftCountItemWidget(1, '一心一意', () {}), + ], + ), + ); + } + + giftCountItemWidget(int count, String desc, GestureTapCallback callback) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + giftCount = count; + isShowCount = false; + setState(() { + + }); + }, + child: Container( + height: 30.sp, + width: 115.sp, + padding: EdgeInsets.only(right: 5.sp), + child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Container( + alignment: Alignment.center, + child: Text( + '${count}', + style: TextStyle(color: Color(0xFFE6E6E6), fontSize: 12.sp), + ))), + Expanded( + child: Container( + alignment: Alignment.center, + child: Text( + desc, + style: TextStyle(color: Color(0xFFE6E6E6), fontSize: 12.sp), + ))), + ], + ), + ), + ); + } +} diff --git a/circle_app/lib/app/chat/widget/partner_option.dart b/circle_app/lib/app/chat/widget/partner_option.dart new file mode 100644 index 0000000..2cef2be --- /dev/null +++ b/circle_app/lib/app/chat/widget/partner_option.dart @@ -0,0 +1,333 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:circle_app/network/api.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:circle_app/util/paymentUtil.dart'; +import 'package:circle_app/util/util.dart'; + +import '../../../common/Widgets/open_vip_tip/logic.dart'; +import '../../../util/PaymentUtils.dart'; + +class PartnerOption extends StatefulWidget { + String accid; + PartnerOption({super.key, required this.accid}); + + @override + _PartnerOptionState createState() => _PartnerOptionState(); +} + +class _PartnerOptionState extends State { + // TODO: add state variables and methods + List priceBean = []; + bool isZfbPrice = true; + List vipName = [ + "vip_year", + "vip_quarter", + "vip_month", + ]; + + List vipTitleName = [ + "年度合伙人", + "季度合伙人", + "月度合伙人", + ]; + + int propsIndex = 0; + + @override + void initState() { + // TODO: implement initState + super.initState(); + iosData(); + } + + iosData() async { + var data = await DioManager.instance.get(url: Api.getVipPrice, params: {}); + var vipPriceList = BaseResponse>.fromJson( + data, + (data) => + List.from(data.map((item) => PriceBean.fromJson(item))), + ); + priceBean = vipPriceList.data; + priceBean = priceBean.reversed.toList(); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + // TODO: add widget build method + return priceBean.isNotEmpty ? vipsWidget() : loaddingWidget(true); + } + + vipsWidget() { + return Container( + width: Get.width, + height: 340.sp, + child: Column( + children: [ + Expanded( + child: ListView.builder( + itemBuilder: (context, index) { + var item = priceBean[index]; + return GestureDetector( + onTap: () { + propsIndex = index; + setState(() {}); + }, + child: Container( + height: 60.sp, + padding: EdgeInsets.only(left: 15.sp, right: 15.sp), + // margin: EdgeInsets.only(right: 5.sp, bottom: 5.sp), + //height: 300, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6.sp), + color: propsIndex == index + ? const Color(0xFF493E5C) + : Colors + .transparent, // Replace this with your desired background drawable + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Image.asset( + getMsgImage(vipName[index]), + width: 48.sp, + height: 48.sp, + fit: BoxFit.cover, + ), + SizedBox(width: 10.sp), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + vipTitleName[index], + style: TextStyle( + color: Colors.white, fontSize: 14.sp), + ), + SizedBox(height: 4.sp), + Text( + '获得会员十几种专属特权' + + (index == 0 + ? '一年' + : index == 1 + ? '3个月' + : '1个月'), + style: TextStyle( + color: Colors.grey, fontSize: 10.sp), + ), + ], + )), + SizedBox(width: 7.sp), + Text( + item.amount.toInt().toString() + '元', + style: TextStyle( + color: AppColor.mainColor, fontSize: 12.sp), + ) + ], + ), + ), + ); + ; + }, + itemCount: 3, + ), + ), + Container( + padding: EdgeInsets.only(left: 16.sp,right: 16.sp,), + height: 48.sp, + width: Get.width, + child: Row( + children: [ + if (Platform.isAndroid) + Container( + // margin: EdgeInsets.only(top: 0.sp,bottom: 20.sp), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + // 处理支付宝支付逻辑 + isZfbPrice = true; + setState(() { + + }); + }, + child: Row( + children: [ + Image.asset( + isZfbPrice? + getMineImage("icon_pay_select"): getMineImage("icon_pay_is_no_select"), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 8.0.sp), + Image.asset( + getMineImage('icon_cooperate_ali'), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 4.0.sp), + Text( + '支付宝支付', + style: TextStyle( + color: const Color(0xFFF7FAFA), + fontSize: 14.0.sp, + ), + ), + SizedBox(width: 4.0.sp), + Image.asset( + getMineImage('icon_recommend_pay_way'), + width: 32.0.sp, + height: 16.0.sp, + ), + ], + ), + ), + SizedBox(width: 8.0.sp), + GestureDetector( + onTap: () { + isZfbPrice = false; + setState(() { + + }); + }, + child: Row( + children: [ + Image.asset( + !isZfbPrice? + getMineImage("icon_pay_select"): getMineImage("icon_pay_is_no_select"), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 8.0.sp), + Image.asset( + getMineImage('icon_cooperate_wx'), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 4.0.sp), + Text( + '微信支付', + style: TextStyle( + color: const Color(0xFFF7FAFA), + fontSize: 14.0.sp, + ), + ), + ], + ), + ), + ], + ), + ), + + Expanded(child: Container()), + GestureDetector( + onTap: () { + iosPay(); + }, + child: Container( + width: 56.sp, + height: 27.sp, + decoration: BoxDecoration( + gradient: AppColor.mainVerLinearGradient, + borderRadius: BorderRadius.circular(13.5.sp)), + alignment: Alignment.center, + child: Text( + '赠送', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w500), + ), + ), + ) + ], + ), + ) + // Container( + // padding: EdgeInsets.only(left: 16.sp, right: 16.sp), + // height: 48.sp, + // width: Get.width, + // child: Row( + // children: [ + // Expanded(child: Container()), + // GestureDetector( + // onTap: () { + // iosPay(); + // }, + // child: + // ), + // ) + // ], + // ), + // ) + ], + ), + ); + } + + iosPay() { + SmartDialog.showLoading(); + String toUserId = widget.accid!.split('_').last; + PriceBean bean = priceBean[propsIndex]; + if (Platform.isAndroid) { + startPayment(); + } else { + IOSPayment.instance + .iosPay(bean.iosItem, bean.id.toString(), 2, userId: toUserId); + } + } + + startPayment() async { + SmartDialog.showLoading(); + String toUserId = widget.accid!.split('_').last; + if (isZfbPrice) { + var data = await DioManager.instance.post( + url: Api.postAliPayOrder, + params: {"product_id": priceBean[propsIndex].id, "type": 2,'target_id':toUserId}); + var bean = BaseResponse.fromJson( + data, (data) => PayUrlBean.fromJson(data)); + if (bean.isSuccess()) { + openAliPay(bean.data.payUrl, (isSuccess, errorMsg) { + if (isSuccess) { + // 处理支付成功 + // refreshVipStatus(); + showOKToast('赠送会员成功'); + } else { + // 处理支付失败,errorMessage 可能为 null + // refreshVipStatus(); + } + }); + } else { + showOKToast(bean.msg); + } + } else { + var data = await DioManager.instance.post( + url: Api.postWxOrder, + params: {"product_id": priceBean[propsIndex].id, "type": 2,'target_id':toUserId}); + var bean = BaseResponse.fromJson( + data, (data) => PaymentData.fromJson(data)); + if (bean.isSuccess()) { + openWxPay(bean.data, (bool isSuccess, String? errorMessage) { + if (isSuccess) { + // 处理支付成功 + showOKToast('赠送会员成功'); + // refreshVipStatus(); + } else { + // 处理支付失败,errorMessage 可能为 null + } + }); + } else { + showOKToast(bean.msg); + } + } + SmartDialog.dismiss(); + } +} diff --git a/circle_app/lib/app/circle/logic.dart b/circle_app/lib/app/circle/logic.dart index 812858b..2c0492d 100644 --- a/circle_app/lib/app/circle/logic.dart +++ b/circle_app/lib/app/circle/logic.dart @@ -520,6 +520,26 @@ class Circle { required this.lastJoinUsers, }); + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['is_limit'] = this.is_limit; + data['image'] = this.image; + data['ios_item'] = this.ios_item; + data['title'] = this.title; + data['intro'] = this.intro; + data['amount'] = this.amount; + data['old_amount'] = this.oldAmount; + data['view_total'] = this.viewTotal; + data['join_total'] = this.joinTotal; + if (this.lastJoinUsers.isNotEmpty) { + var list = this.lastJoinUsers.map((e) => e.toJson()).toList(); + data['last_join_users'] = list; + } + + return data; + } + factory Circle.fromJson(Map json) { List lastJoinUsers = []; if (json.containsKey('last_join_users')) { @@ -554,12 +574,20 @@ class JoinUser { String avatar; String nickname; + + Map toJson() { + final Map data = new Map(); + data['avatar'] = this.avatar; + return data; + } + JoinUser({ required this.id, required this.avatar, required this.nickname, }); + factory JoinUser.fromJson(Map json) { return JoinUser( id: json['id'], diff --git a/circle_app/lib/app/circle/widgets/like_view.dart b/circle_app/lib/app/circle/widgets/like_view.dart index b1b26b9..a254505 100644 --- a/circle_app/lib/app/circle/widgets/like_view.dart +++ b/circle_app/lib/app/circle/widgets/like_view.dart @@ -151,6 +151,7 @@ class _LikeViewState extends State if (recomandPage == 2 || recomandPage == 1) { refreshController.refreshCompleted(); + refreshController.loadComplete(); } else { if (recomandMore) { refreshController.loadComplete(); diff --git a/circle_app/lib/app/gift_shop/binding.dart b/circle_app/lib/app/gift_shop/binding.dart new file mode 100644 index 0000000..306e787 --- /dev/null +++ b/circle_app/lib/app/gift_shop/binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'logic.dart'; + +class Gift_shopBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => Gift_shopLogic()); + } +} diff --git a/circle_app/lib/app/gift_shop/logic.dart b/circle_app/lib/app/gift_shop/logic.dart new file mode 100644 index 0000000..b24a5b5 --- /dev/null +++ b/circle_app/lib/app/gift_shop/logic.dart @@ -0,0 +1,93 @@ +import 'package:get/get.dart'; +import 'package:circle_app/network/api.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:circle_app/util/util.dart'; + +import '../../common/Widgets/base_tip_widget.dart'; +import '../../components/func_widget.dart'; +import '../../util/SharedPreferencesHelper.dart'; + +class Gift_shopLogic extends GetxController { + String userId = Get.arguments; + + List giftList = []; + + List recevigiftList = []; + + int total = 0; + String topTitle = ''; + Map toUser = {}; + + String accid = ''; + + @override + void onInit() { + // TODO: implement onInit + super.onInit(); + loadGiftListData(); + } + + loadGiftListData() async { + var result = await DioManager.instance.get(url: Api.giftList); + if (result['code'] == 200) { + giftList = result['data']; + loadData(); + } + } + + void loadData() async { + SharedPreferencesHelper sp = await SharedPreferencesHelper.getInstance(); + String myId = sp.getMyUserId(); + + var result = await DioManager.instance.get( + url: userId.toString().isNotEmpty ? Api.giftHall + userId : Api.giftHall + myId, + ); + if (result['code'] == 200) { + topTitle = result['data']['topDesc']; + toUser = result['data']['topUser'] ?? {}; + total = result['data']['receiveTotal']; + // "accid" -> "ky_dev_30629" + accid = result['data']['imId']; + // receiveGiftNum + recevigiftList = result['data']['receiveGiftNum']; + if (recevigiftList.isNotEmpty) { + var receiveList = []; + var noreceiveList = []; + giftList.forEach((element) { + bool isContain = false; + for (var info in recevigiftList) { + if (element['id'] == info['giftId']) { + isContain = true; + } + } + if (isContain) { + receiveList.add(element); + } else { + noreceiveList.add(element); + } + }); + receiveList.addAll(noreceiveList.reversed.toList()); + giftList = receiveList; + update(); + } + update(); + } + } + + void sendGiftData(String accid, String giftId, String userId, int index, + String discoverId) async { + var result = await DioManager.instance.post(url: Api.sendGift, params: { + 'accid': accid, + 'giftId': giftId, + 'num': 1, + 'toUserId': userId + }); + if (result['code'] == 200) { + showOKToast('赠送成功'); + loadData(); + } else if (result['code'] == 31201) { + showOKToast(result['msg']); + showRechargeScreenDialog(); + } + } +} diff --git a/circle_app/lib/app/gift_shop/view.dart b/circle_app/lib/app/gift_shop/view.dart new file mode 100644 index 0000000..c2475d2 --- /dev/null +++ b/circle_app/lib/app/gift_shop/view.dart @@ -0,0 +1,353 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:circle_app/components/my_app_bar.dart'; +import 'package:circle_app/util/util.dart'; + +import '../../common/colors/app_color.dart'; +import '../../common/values/values.dart'; +import '../../components/func_widget.dart'; +import '../../router/app_routers.dart'; +import 'logic.dart'; + +class Gift_shopPage extends StatelessWidget { + Gift_shopPage({ + Key? key, + }) : super(key: key); + + final logic = Get.find(); + + @override + Widget build(BuildContext context) { + return GetBuilder(builder: (logic) { + return Scaffold( + backgroundColor: Colors.black, + appBar: MyAppBar( + centerTitle: logic.userId.isNotEmpty ? 'Ta的礼物馆' : '我的礼物馆', + actionWdiget: logic.userId.isNotEmpty + ? Container() + : GestureDetector( + onTap: () { + Get.toNamed(AppRoutes.BillActivity,arguments: 2); + }, + child: Text( + '礼物收入', + style: TextStyle(color: Colors.white, fontSize: 14.sp), + ), + ), + ), + body: SingleChildScrollView( + child: Column( + children: [ + //贡献之星 + topStartWidget(), + //收到的礼物 + receverGiftWidget() + ], + ), + ), + ); + }); + } + + topStartWidget() { + return Container( + width: Get.width, + height: 160.sp, + child: Stack( + alignment: Alignment.center, + children: [ + if (logic.toUser.isEmpty) + Container( + width: Get.width - 32.sp, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset( + getMineImage('gift_no_data_bg'), + width: Get.width - 32.sp, + fit: BoxFit.fill, + ), + Positioned( + left: 20.sp, + child: Image.asset( + getMineImage('gift_no_data'), + width: 48.sp, + )), + Text( + '贡献之星正在来得路上~', + style: TextStyle(color: Colors.white, fontSize: 15.sp), + ), + ], + ), + ), + if (logic.toUser.isNotEmpty) userItem(), + Positioned( + top: 0.sp, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset( + getMineImage('gift_top_star'), + width: 140.sp, + ), + Container( + margin: EdgeInsets.only(top: 10.sp), + child: Text( + logic.topTitle + '贡献之星', + style: TextStyle(color: Colors.white, fontSize: 15.sp), + ), + ) + ], + )) + ], + ), + ); + } + + userItem() { + return Container( + height: 160.sp, + child: Stack( + alignment: Alignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(6.sp), + child: Stack( + children: [ + Image.network( + logic.toUser['avatar'] ?? + 'http://qiniuyun.ikuayou.com/avatar/default/default_header.png', + width: Get.width - 32.sp, + height: 100.sp, + fit: BoxFit.cover, + ), + Container(color: Colors.black.withOpacity(0.75), width: Get.width - 32.sp, + height: 100.sp,) + ], + ) + ), + GestureDetector( + onTap: () { + Get.toNamed(AppRoutes.UserInfoActivity,arguments: logic.toUser['id'].toString()); + }, + child: Container( + padding: EdgeInsets.only(left: 32.sp), + child: Row( + children: [ + ClipOval( + child: CachedNetworkImage( + fit: BoxFit.cover, + imageUrl: logic.toUser['avatar'] ?? + 'http://qiniuyun.ikuayou.com/avatar/default/default_header.png', + width: 45.sp, + height: 45.sp, + ), + ), + SizedBox(width: 10.sp), + Container( + margin: EdgeInsets.only(top: 55.sp), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + constraints: BoxConstraints( + maxWidth: 120.sp, + ), + child: Text( + logic.toUser['nickname'], + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + color: logic.toUser['vip'] > 0 + ? Color(0xffDE0049) + : Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.bold), + ), + ), + SizedBox(width: 4.sp), + if (logic.toUser.isNotEmpty) + _buildInfoRow(), + ], + ), + SizedBox(height: 6.sp), + Container( + width: 250.sp, + child: Text( + '${logic.topTitle}送了${logic.toUser['giftNum']['num']}个礼物,价值${logic.toUser['giftNum']['amount']}跨豆', + style: + TextStyle(fontSize: 13.sp, color: Colors.white), + ), + ), + ], + ), + ), + ], + ), + ), + ) + ], + ), + ); + } + + Widget _buildInfoRow() { + String ageMsg = logic.toUser['genderDesc']; + + return Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17), + gradient: const LinearGradient( + colors: [ + Color.fromRGBO(141, 255, 248, 1.0), + Color.fromRGBO(181, 211, 255, 1.0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.only( + top: 2.sp, + bottom: 2.sp, + left: 10.sp, + right: 10.sp, + ), + child: Text( + ageMsg, + style: const TextStyle( + color: Colors.black, + fontSize: 10, + ), + ), + ), + const SizedBox(width: 6), + if (logic.toUser['vip'] > 0) + Image( + image: AssetImage( + getBaseImage(logic.toUser['vip'] == 1 ? "vip" : 'year_vip')), + width: 44.sp, + height: 18.sp, + ), + ], + ); + } + + receverGiftWidget() { + return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Container( + margin: EdgeInsets.only(left: 16.sp, bottom: 15.sp), + child: Text( + '收到的礼物 (${logic.total}个)', + style: TextStyle(color: Colors.white, fontSize: 15.sp), + ), + ), + Container( + width: Get.width, + height: 505.sp, + padding: EdgeInsets.only(left: 16.sp, right: 16.sp), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 8.0.sp, + mainAxisSpacing: 8.0.sp, + childAspectRatio: 0.75, + ), + itemCount: logic.giftList.length, + // Replace with the actual item count + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + // Replace the placeholders with the actual item widgets + return giftItemWidget(logic.giftList[index], index); + }, + )) + ]); + } + + giftItemWidget(Map info, int index) { + bool isGet = false; + int num = 0; + logic.recevigiftList.forEach((element) { + if (element['giftId'] == info['id']) { + isGet = true; + num = element['num']; + } + }); + + double price = info['price']; + + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () {}, + child: Container( + height: 105.sp, + decoration: BoxDecoration( + color: isGet ? Color(0xFF3E3D4C) : Color(0x292836FF), + borderRadius: BorderRadius.circular(4.sp), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Opacity( + opacity: isGet ? 1 : 0.5, + child: Image.network( + info['icon'], + width: 60.sp, + height: 60.sp, + fit: BoxFit.cover, + ), + ), + SizedBox( + height: 5.sp, + ), + Text(num > 0 ? info['name'] + 'x' + getGiftCountValue(num).toString() : info['name'], + style: TextStyle( + color: isGet ? Colors.white : Color(0x898F99FF), + fontSize: 13.sp, + fontWeight: FontWeight.w500)), + GestureDetector( + onTap: () { + logic.sendGiftData(logic.accid, info['id'].toString(), + logic.userId, index, ''); + }, + child: Container( + height: 20.sp, + width: 52.sp, + margin: EdgeInsets.only(top: 10.sp), + // padding: EdgeInsets.only(left: 5.sp,right: 5.sp), + alignment: Alignment.center, + decoration: BoxDecoration( + gradient: AppColor.mainVerLinearGradient, + borderRadius: BorderRadius.circular(10.sp)), + child: Text( + !isGet ? '去送礼' : '赠送', + style: TextStyle(color: Colors.white, fontSize: 11.sp), + ), + ), + ) + ], + ), + ), + ); + } +} + + + +getGiftCountValue(int value) { + if (value >= 10000) { + double populartityValue = value / 10000; + return '${populartityValue.toStringAsFixed(1)}W'; + } if (value >= 1000) { + double populartityValue = value / 1000; + return '${populartityValue.toStringAsFixed(1)}K'; + } else { + return value; + } +} diff --git a/circle_app/lib/app/likelist/logic.dart b/circle_app/lib/app/likelist/logic.dart index db5a690..a289651 100644 --- a/circle_app/lib/app/likelist/logic.dart +++ b/circle_app/lib/app/likelist/logic.dart @@ -1,4 +1,3 @@ - import 'package:circle_app/app/minefragment/logic.dart'; import 'package:get/get.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; @@ -12,8 +11,8 @@ class LikelistLogic extends GetxController { void dispose() { refreshController.dispose(); super.dispose(); - } + final RefreshController refreshController = RefreshController(); final LikelistState state = LikelistState(); @@ -22,47 +21,41 @@ class LikelistLogic extends GetxController { bool isLoad = true; List lists = []; @override - void onInit() async{ + void onInit() async { super.onInit(); var mineLogic = Get.find(); isVip = mineLogic.isVip.value; initList(); } - - initList() async{ - if(page==1){ + initList() async { + if (page == 1) { lists.clear(); } - var data = - await DioManager.instance.get(url: Api.fansList, params: { - 'page':page - }); - var bean = BaseResponse.fromJson(data, (data) => UserList.fromJson(data)); - if (bean.isSuccess()) { - lists.addAll(bean.data.lists); - } - isLoad = false; - update(); - if(page == 1){ - refreshController.refreshCompleted(); - }else{ - refreshController.loadComplete(); - } - - - + var data = await DioManager.instance + .get(url: Api.fansList, params: {'page': page}); + var bean = BaseResponse.fromJson( + data, (data) => UserList.fromJson(data)); + if (bean.isSuccess()) { + lists.addAll(bean.data.lists); + } + isLoad = false; + update(); + if (page == 1) { + refreshController.refreshCompleted(); + } else { + refreshController.loadComplete(); + } } - setLike(int index) async { var data = await DioManager.instance.post( url: "${Api.setLike + lists[index].user.id.toString()}/follow", - params: {'status': lists[index].isLike?"0":"1"}); + params: {'status': lists[index].isLike ? "0" : "1"}); var bean = BaseResponse.fromJson( data, - (jsonData) => jsonData, + (jsonData) => jsonData, ); if (bean.isSuccess()) { lists[index].isLike = !lists[index].isLike; @@ -70,12 +63,8 @@ class LikelistLogic extends GetxController { } showOKToast(bean.msg); } - } - - - class User { final int id; final String nickname; @@ -90,6 +79,7 @@ class User { final double lng; final double lat; final String city; + final String imId; final String avatarThumb; User({ @@ -104,6 +94,7 @@ class User { required this.role, required this.orientation, required this.lng, + required this.imId, required this.lat, required this.city, required this.avatarThumb, @@ -117,6 +108,7 @@ class User { signature: json['signature'], birthday: json['birthday'], age: json['age'], + imId: json['imId'] ?? '', vip: json['vip'], gender: json['gender'], role: json['role'], @@ -131,7 +123,7 @@ class User { class UserListItem { final User user; - bool isLike; + bool isLike; UserListItem({ required this.user, @@ -166,4 +158,3 @@ class UserList { ); } } - diff --git a/circle_app/lib/app/login/complete_material/logic.dart b/circle_app/lib/app/login/complete_material/logic.dart index 2ef9a7b..d801582 100644 --- a/circle_app/lib/app/login/complete_material/logic.dart +++ b/circle_app/lib/app/login/complete_material/logic.dart @@ -223,6 +223,9 @@ class Complete_materialLogic extends GetxController { } else if (state.descEditingController.text.length < 5) { showOKToast('您的交友宣言太短'); return; + } else if (state.descEditingController.text.length > 40) { + showOKToast('您的交友宣言超出40个字啦'); + return; } diff --git a/circle_app/lib/app/minefragment/view.dart b/circle_app/lib/app/minefragment/view.dart index 57b2963..15e11e6 100644 --- a/circle_app/lib/app/minefragment/view.dart +++ b/circle_app/lib/app/minefragment/view.dart @@ -165,7 +165,7 @@ class _MinefragmentPageState extends State with RouteAware { return Column( - children: [_circleItemView(logic),_invienItemView(),_editGoodReviewItemView(), _helpItemView(),_setUpItemView()], + children: [_myAssetItemView(),_circleItemView(logic),_invienItemView(),_editGoodReviewItemView(), _helpItemView(),_setUpItemView()], ); } @@ -425,6 +425,47 @@ class _MinefragmentPageState extends State with RouteAware { ); } + Widget _myAssetItemView() { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + Get.toNamed(AppRoutes.MyAssets); + }, + child: Container( + margin: EdgeInsets.only(top: 18.sp), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Image( + image: AssetImage(getMineImage("wallet")), + width: 24.sp, + height: 24.sp, + ), + SizedBox(width: 10.sp), + const Text( + "我的资产", + style: TextStyle(color: Colors.white), + ), + ], + ), + Row( + children: [ + + Image( + image: AssetImage(getHomeImage("icon_in")), + width: 24.sp, + height: 24.sp, + ), + ], + ) + ], + ), + ), + ); + } + Widget _circleItemView(MinefragmentLogic logic) { return GestureDetector( behavior: HitTestBehavior.opaque, diff --git a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart index 111fabc..cb69624 100644 --- a/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart +++ b/circle_app/lib/app/msg/TIMUIKitConversation/tim_uikit_conversation_item.dart @@ -118,14 +118,8 @@ class TIMConversationItem extends TIMUIKitStatelessWidget { Widget _getTimeStringForChatWidget(BuildContext context, TUITheme theme) { try { - if (draftTimestamp != null && draftTimestamp != 0) { - return Text(TimeAgo().getTimeStringForChat(draftTimestamp as int), - style: TextStyle( - fontSize: 12, - color: theme.conversationItemTitmeTextColor, - )); - } else if (lastMsg != null) { - return Text(TimeAgo().getTimeStringForChat(lastMsg!.timestamp as int), + if (lastMsg != null) { + return Text(TimeAgo().getTimeForMessage(lastMsg!.timestamp as int), style: TextStyle( fontSize: 11, color: theme.conversationItemTitmeTextColor, diff --git a/circle_app/lib/app/my_assets/binding.dart b/circle_app/lib/app/my_assets/binding.dart new file mode 100644 index 0000000..f76cc3b --- /dev/null +++ b/circle_app/lib/app/my_assets/binding.dart @@ -0,0 +1,10 @@ +import 'package:get/get.dart'; + +import 'logic.dart'; + +class My_assetsBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => My_assetsLogic()); + } +} diff --git a/circle_app/lib/app/my_assets/logic.dart b/circle_app/lib/app/my_assets/logic.dart new file mode 100644 index 0000000..35e20fb --- /dev/null +++ b/circle_app/lib/app/my_assets/logic.dart @@ -0,0 +1,127 @@ +import 'package:circle_app/util/eventBus.dart'; +import 'package:get/get.dart'; + +import '../../network/api.dart'; +import '../../network/dio_manager.dart'; + +class My_assetsLogic extends GetxController { + + AssetsDataData? myAssest; + var sub; + @override + void onInit() { + // TODO: implement onInit + super.onInit(); + sub = EventBusManager.on().listen((event) { + loadMyAssest(); + }); + loadMyAssest(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + sub.cancel(); + } + + void loadMyAssest() async { + var data = await DioManager.getInstance().get(url: Api.userAsset); + if (data['code'] == 200) { + myAssest = AssetsDataData.fromJson(data['data']); + update(); + } + } +} + + +/// +/// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/ +/// +class AssetsDataData { +/* +{ + "balance": 0, + "incomeBalance": 0, + "totalExpenseBalance": 0, + "totalIncomeBalance": 0, + "totalRechargeBalance": 0, + "totalWithDrawBalance": 0 +} +*/ + + int? balance; + int? incomeBalance; + int? totalExpenseBalance; + int? totalIncomeBalance; + int? totalRechargeBalance; + int? totalWithDrawBalance; + + AssetsDataData({ + this.balance, + this.incomeBalance, + this.totalExpenseBalance, + this.totalIncomeBalance, + this.totalRechargeBalance, + this.totalWithDrawBalance, + }); + AssetsDataData.fromJson(Map json) { + balance = json['balance']?.toInt(); + incomeBalance = json['incomeBalance']?.toInt(); + totalExpenseBalance = json['totalExpenseBalance']?.toInt(); + totalIncomeBalance = json['totalIncomeBalance']?.toInt(); + totalRechargeBalance = json['totalRechargeBalance']?.toInt(); + totalWithDrawBalance = json['totalWithDrawBalance']?.toInt(); + } + Map toJson() { + final data = {}; + data['balance'] = balance; + data['incomeBalance'] = incomeBalance; + data['totalExpenseBalance'] = totalExpenseBalance; + data['totalIncomeBalance'] = totalIncomeBalance; + data['totalRechargeBalance'] = totalRechargeBalance; + data['totalWithDrawBalance'] = totalWithDrawBalance; + return data; + } +} + +class AssetsData { +/* +{ + "code": 0, + "data": { + "balance": 0, + "incomeBalance": 0, + "totalExpenseBalance": 0, + "totalIncomeBalance": 0, + "totalRechargeBalance": 0, + "totalWithDrawBalance": 0 + }, + "msg": "" +} +*/ + + int? code; + AssetsDataData? data; + String? msg; + + AssetsData({ + this.code, + this.data, + this.msg, + }); + AssetsData.fromJson(Map json) { + code = json['code']?.toInt(); + data = (json['data'] != null) ? AssetsDataData.fromJson(json['data']) : null; + msg = json['msg']?.toString(); + } + Map toJson() { + final data = {}; + data['code'] = code; + if (data != null) { + data['data'] = this.data!.toJson(); + } + data['msg'] = msg; + return data; + } +} diff --git a/circle_app/lib/app/my_assets/view.dart b/circle_app/lib/app/my_assets/view.dart new file mode 100644 index 0000000..4a5eecb --- /dev/null +++ b/circle_app/lib/app/my_assets/view.dart @@ -0,0 +1,281 @@ +import 'dart:io'; + +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:circle_app/components/my_app_bar.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; + +import '../../common/Widgets/RechargeScreenDialog.dart'; +import '../../router/app_routers.dart'; +import '../../util/util.dart'; +import 'logic.dart'; + +class My_assetsPage extends StatelessWidget { + My_assetsPage({Key? key}) : super(key: key); + + final logic = Get.find(); + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery + .of(context) + .size + .width, + height: MediaQuery + .of(context) + .size + .height, + decoration: BoxDecoration( + color: Color(0xFF423055), + image: DecorationImage( + fit: BoxFit.fill, + image: AssetImage(getBaseImage('home_back')))), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: MyAppBar( + centerTitle: '我的资产', + actionWdiget: GestureDetector( + onTap: () { + Get.toNamed(AppRoutes.BillActivity); + }, + child: Text('账单', + style: TextStyle(color: Color(0xFF00FFF4), fontSize: 14.sp),), + ), + onPressed: () { + Get.toNamed(AppRoutes.BillActivity); + }, + ), + body: GetBuilder(builder: (logic) { + return logic.myAssest != null ? SingleChildScrollView( + child: Column( + children: [ + Container( + padding: EdgeInsets.only(left: 15.sp, right: 15.sp), + child:Stack( + children: [ + Image.asset( + getMineImage("im_ky_bc"), + // Replace with the path to the image asset + fit: BoxFit.cover, + ), + Positioned( + // left: 0, + // right: 0, + left: Get.width / 2 - 17, + top: 25, + bottom: 85, + // Replace this with the desired position of your line + child: Container( + width: 0.3, + color: Color( + 0x4DFFFFFF), // Replace this with the color of your line + ), + ), + Column( + children: [ + Container( + // height: 100.sp, + margin: EdgeInsets.only(top: 19.sp), + child: Row( + children: [ + Expanded( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "总资产余额", + style: TextStyle( + color: Colors.white, + fontSize: 13.sp), + ), + SizedBox(width: 4.sp,), + GestureDetector( + onTap: () { + showOKToast( + '总资产包括您充值的小票,收入小票等所有可使用的小票。'); + }, + child: Image.asset( + getMineImage('wen'), width: 18.sp,) + ), + ], + ), + ), + Expanded( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "收入金额", + style: TextStyle( + color: Colors.white, + fontSize: 13.sp), + ), + // if (Platform.isAndroid) + SizedBox(width: 4.sp), + // if (Platform.isAndroid) + GestureDetector( + onTap: () { + var con; + if(kDebugMode){ + con = V2TimConversation( + conversationID: "c2c_qpqz_dev_10_102", userID: "qpqz_dev_10_102", showName: "测试乐园客服", type: 1); + }else{ + con = V2TimConversation( + conversationID: "c2c_qpqz_prod_10_102", userID: "qpqz_prod_10_102", showName: "乐园客服", type: 1); + } + Get.toNamed(AppRoutes.Chat, arguments: con); + }, + child: Container( + height: 20.sp, + padding: EdgeInsets.only(left: 6.sp,right: 6.sp), + alignment: Alignment.center, + decoration: BoxDecoration( + gradient: AppColor + .mainVerLinearGradient, + borderRadius: BorderRadius + .circular(10.sp) + ), + child: Text('联系客服', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp),), + ), + ) + ], + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 16.sp), + child: Row( + children: [ + Expanded( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + + "${logic.myAssest!.balance!}小票", + style: TextStyle( + color: Colors.white, + fontSize: 18.sp), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "${logic.myAssest!.incomeBalance!}小票", + style: TextStyle( + color: Colors.white, + fontSize: 18.sp), + ), + ], + ), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only( + top: 24.sp, left: 16.sp, right: 16.sp), + width: Get.width, + height: 1.sp, + color: Color(0x4DFFFFFF), + ), + Container( + margin: EdgeInsets.only(top: 16.sp), + child: Row( + children: [ + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "总充值", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + Text("${logic.myAssest!.totalRechargeBalance!}小票", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "总收入", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + Text( + "${logic.myAssest!.totalIncomeBalance!}小票", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "总支出", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + Text("${logic.myAssest!.totalExpenseBalance!}小票", + style: TextStyle( + color: Colors.white, + fontSize: 12.sp), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ], + )), + Container( + margin: EdgeInsets.only(top: 16.sp), + height: 401.sp, + width: Get.width, + child: RechargeScreenDialog(isShowBalance: false,), + ) + ], + ), + + ) : loaddingWidget(true); + }), + )); + } +} diff --git a/circle_app/lib/app/userinfo/logic.dart b/circle_app/lib/app/userinfo/logic.dart index c8b80ca..81549a1 100644 --- a/circle_app/lib/app/userinfo/logic.dart +++ b/circle_app/lib/app/userinfo/logic.dart @@ -10,6 +10,7 @@ import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_ser import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import '../../common/Widgets/base_tip_widget.dart'; import '../../common/config.dart'; import '../../network/api.dart'; import '../../network/dio_manager.dart'; @@ -43,6 +44,12 @@ class UserinfoLogic extends GetxController { bool isBlackBeen = false; bool isDestroy = false; + List giftList = []; + + List recevigiftList = []; + + Map toUser = {}; + int unLockWxNum = 0; final startTime = DateTime.now(); SharedPreferences? sharedPreferences; @@ -83,6 +90,54 @@ class UserinfoLogic extends GetxController { } SmartDialog.dismiss(); fetchQnToken(Api.getqiniuToken); + loadGiftListData(); + } + + loadGiftListData() async { + var result = await DioManager.instance.get(url: Api.giftList); + if (result['code'] == 200) { + giftList = result['data']; + loadData(); + } + } + + void loadData() async { + SharedPreferencesHelper sp = await SharedPreferencesHelper.getInstance(); + String myId = sp.getMyUserId(); + + var result = await DioManager.instance.get( + url: userId.toString().isNotEmpty ? Api.giftHall + userId : Api.giftHall + myId, + ); + if (result['code'] == 200) { + // topTitle = result['topDesc']; + toUser = result['data']['topUser'] ?? {}; + // total = result['receiveTotal']; + // "accid" -> "ky_dev_30629" + // accid = result['accid']; + // receiveGiftNum + recevigiftList = result['data']['receiveGiftNum']; + if (recevigiftList.isNotEmpty) { + var receiveList = []; + var noreceiveList = []; + giftList.forEach((element) { + bool isContain = false; + for (var info in recevigiftList) { + if (element['id'] == info['giftId']) { + isContain = true; + } + } + if (isContain) { + receiveList.add(element); + } else { + noreceiveList.add(element); + } + }); + receiveList.addAll(noreceiveList.reversed.toList()); + giftList = receiveList; + update(); + } + update(); + } } @@ -287,6 +342,23 @@ class UserinfoLogic extends GetxController { showOKToast(bean.msg); } + + void sendGiftData(String accid, String giftId, String userId, ) async { + var result = await DioManager.instance.post(url: Api.sendGift, params: { + 'accid': accid, + 'giftId': giftId, + 'num': 1, + 'toUserId': userId + }); + if (result['code'] == 10000) { + showOKToast('赠送成功'); + loadData(); + } else if (result['code'] == 31201) { + showOKToast(result['msg']); + showRechargeScreenDialog(); + } + } + Future getImageFile() async { try { final XFile? pickedFile = await _picker.pickImage( diff --git a/circle_app/lib/app/userinfo/view.dart b/circle_app/lib/app/userinfo/view.dart index 7de44b8..0993069 100644 --- a/circle_app/lib/app/userinfo/view.dart +++ b/circle_app/lib/app/userinfo/view.dart @@ -428,6 +428,137 @@ class MyTabbedScreenState extends State wxStatusWidget(logic.unLockWxNum == 1,logic.userInfoBean!.wx_num, logic.userInfoBean!.id.toString(),logic.userInfoBean!.avatar!, (){}), ], )) : Container() : Container(), + + if (logic.userInfoBean != null && logic.giftList.isNotEmpty) + GestureDetector( + onTap: () async { + + var result = await Get.toNamed(AppRoutes.GiftShopPage, + arguments: logic.imId.split('_').last); + logic.loadGiftListData(); + }, + child: Container( + margin: EdgeInsets.only(top: 0.sp,left: 15.sp,right: 15.sp), + padding: EdgeInsets.only( + left: 12.sp, right: 12.sp, bottom: 18.sp, top: 16.sp), + height: 144.sp, + decoration: BoxDecoration( + color: Color(0x1AFFFFFF), + borderRadius: BorderRadius.circular(14.sp)), + child: Column( + children: [ + Container( + child: Row( + children: [ + Image.asset( + getMineImage('gift_shop_icon'), + width: 65.sp, + ), + Expanded(child: Container()), + Text( + logic.toUser.isNotEmpty ? '贡献之星' : '贡献之星还在路上', + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + ), + ), + if (logic.toUser.isNotEmpty) + SizedBox( + width: 6.sp, + ), + if (logic.toUser.isNotEmpty) + Text( + '${logic.toUser['nickname']}', + style: TextStyle( + color: AppColor.mainColor, + fontSize: 14.sp, + ), + ), + SizedBox( + width: 8.sp, + ), + Image.asset( + getMineImage('chevron_left'), + width: 14.sp, + ), + ], + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 10.sp), + alignment: Alignment.centerLeft, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: logic.giftList.length, + itemBuilder: (BuildContext context, int giftIndex) { + var info = logic.giftList[giftIndex]; + bool isGet = false; + int num = 0; + logic.recevigiftList.forEach((element) { + if (element['giftId'] == info['id']) { + isGet = true; + num = element['num']; + } + }); + return GestureDetector( + onTap: () {}, + child: Container( + margin: EdgeInsets.only(right: 10.sp), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack(children: [ + Opacity( + opacity: !isGet ? 0.5 : 1, + child: Image.network( + info['icon'], + width: 50.sp, + height: 50.sp, + fit: BoxFit.cover, + ), + ), + ]), + SizedBox( + height: 6.sp, + ), + GestureDetector( + onTap: () { + logic.sendGiftData( + logic.imId, + info['id'].toString(), + logic.imId.split('_').last, + ); + }, + child: Container( + height: 20.sp, + width: 52.sp, + // padding: EdgeInsets.only(left: 5.sp,right: 5.sp), + alignment: Alignment.center, + decoration: BoxDecoration( + gradient: AppColor + .mainVerLinearGradient, + borderRadius: + BorderRadius.circular(10.sp)), + child: Text( + !isGet ? '点亮' : '赠送', + style: TextStyle( + color: Colors.white, + fontSize: 11.sp), + ), + ), + ) + ], + ), + ), + ); + }), + )) + ], + ), + ), + ), + titleTab(controller), Expanded( diff --git a/circle_app/lib/common/Widgets/RechargeScreenDialog.dart b/circle_app/lib/common/Widgets/RechargeScreenDialog.dart new file mode 100644 index 0000000..fd8684d --- /dev/null +++ b/circle_app/lib/common/Widgets/RechargeScreenDialog.dart @@ -0,0 +1,605 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:circle_app/common/colors/app_color.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:get/get_core/src/get_main.dart'; +import 'package:circle_app/app/home/logic.dart'; +import 'package:circle_app/app/minefragment/logic.dart'; +import 'package:circle_app/main.dart'; +import 'package:circle_app/network/dio_manager.dart'; +import 'package:circle_app/util/PaymentUtils.dart'; +import 'package:circle_app/util/eventBus.dart'; +import 'package:circle_app/util/paymentUtil.dart'; +import 'package:circle_app/util/util.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; + +import '../../network/api.dart'; +import '../../router/app_routers.dart'; +import 'open_vip_tip/logic.dart'; + +class RechargeScreenDialog extends StatefulWidget { + bool isShowBalance; + RechargeScreenDialog({super.key,required this.isShowBalance}); + + @override + _RechargeScreenDialogState createState() => _RechargeScreenDialogState(); +} + +class _RechargeScreenDialogState extends State { + + String incomeBalance = ''; + bool isZfbPrice = true; + + bool isAgree = false; + + var logic = Get.find(); + @override + void initState() { + super.initState(); + + gelectThirdItem(); + + } + + List walletRechargeSelectItemBos = []; + + + void gelectThirdItem() async { + var data = await DioManager.getInstance().get(url: Api.walletRechargeSelectItem); + if (data['code'] == 200) { + // "walletRechargeSelectItemBos" -> [_GrowableList] + List response =data['data']['priceConfs']; + + incomeBalance = data['data']['balance'].toString(); + // List walletRechargeSelectItemBos = []; + + response.forEach((element) { + AssetsDataDataPriceConfs item = AssetsDataDataPriceConfs.fromJson(element); + if (walletRechargeSelectItemBos.isEmpty) { + item.isSelected = true; + } + walletRechargeSelectItemBos.add(item); + }); + setState(() {}); + } + + } + + startPayment(String itemId) async { + SmartDialog.showLoading(); + if (isZfbPrice) { + var data = await DioManager.instance.post( + url: Api.postAliPayOrder, + params: {"itemId": itemId, "payType": 4}); + if (data['code'] == 10000) { + openAliPay(data['payUrl'], (isSuccess, errorMsg) { + if (isSuccess) { + // 处理支付成功 + showOKToast('充值成功'); + EventBusManager.fire(AssestEvent()); + } else { + // 处理支付失败,errorMessage 可能为 null + // refreshVipStatus(); + } + }); + } else { + showOKToast(data['msg']); + } + } else { + var data = await DioManager.instance.post( + url: Api.postWxOrder, + params: {"itemId": itemId, "payType": 4}); + var bean = BaseResponse.fromJson( + data, (data) => PaymentData.fromJson(data)); + if (bean.isSuccess()) { + // "wxPayAo" -> [_Map] + openWxPay(data['wxPayAo'], (bool isSuccess, String? errorMessage) { + if (isSuccess) { + // 处理支付成功 + showOKToast('充值成功'); + EventBusManager.fire(AssestEvent()); + } else { + // 处理支付失败,errorMessage 可能为 null + } + }); + } else { + showOKToast(bean.msg); + } + } + SmartDialog.dismiss(); + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor:Colors.transparent, + body: Stack( + alignment: Alignment.center, + children:[ + if (widget.isShowBalance) + Container(width: Get.width,height: Get.height,), + Container( + margin: EdgeInsets.only(left: 20.sp,right: 20.sp), + padding: EdgeInsets.all(20.sp), + height: widget.isShowBalance ? 441.sp + (!Platform.isAndroid ? 0 : 50.sp) : 390.sp + (!Platform.isAndroid ? 0 : 50.sp), + decoration: BoxDecoration( + color: const Color(0xFF393949), + borderRadius: BorderRadius.circular(10.sp) + ), + child: Column( + + children: [ + if (widget.isShowBalance) + Stack( + alignment: Alignment.center, + children: [ + Container(width:Get.width,), + Text( + '小票充值', + style: TextStyle( + color: const Color(0xFFF7FAFA), fontSize: 16.0.sp), + ), + Positioned( + right: 0.sp, + child: IconButton( + icon: const Icon(Icons.close, color: Colors.white), + onPressed: () => Navigator.pop(context), + ), + ), + ], + ), + if (widget.isShowBalance) + Container( + margin: EdgeInsets.only(top: 10.0.sp), + alignment: Alignment.topLeft, + child: Text( + '小票余额:${incomeBalance}', + style: TextStyle( + color: const Color(0xFFEFD84E), fontSize: 14.0.sp), + ), + ), + if (widget.isShowBalance) + SizedBox(height: 5.0.sp), + ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: walletRechargeSelectItemBos.length, + itemBuilder: (context, index) { + return itemView( + context, walletRechargeSelectItemBos[index], index); + }, + ), + !Platform.isAndroid ? Container( + height: 10.sp, + ): Container( + margin: EdgeInsets.only(top: 4.sp,bottom: 10.sp), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + // 处理支付宝支付逻辑 + isZfbPrice = true; + setState(() { + + }); + }, + child: Row( + children: [ + Image.asset( + isZfbPrice? + getMineImage("icon_pay_select"): getMineImage("icon_pay_is_no_select"), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 8.0.sp), + Image.asset( + getMineImage('icon_cooperate_ali'), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 4.0.sp), + Text( + '支付宝支付', + style: TextStyle( + color: const Color(0xFFF7FAFA), + fontSize: 14.0.sp, + ), + ), + SizedBox(width: 4.0.sp), + Image.asset( + getMineImage('icon_recommend_pay_way'), + width: 32.0.sp, + height: 16.0.sp, + ), + ], + ), + ), + SizedBox(width: 24.0.sp), + GestureDetector( + onTap: () { + isZfbPrice = false; + setState(() { + + }); + }, + child: Row( + children: [ + Image.asset( + !isZfbPrice? + getMineImage("icon_pay_select"): getMineImage("icon_pay_is_no_select"), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 8.0.sp), + Image.asset( + getMineImage('icon_cooperate_wx'), + width: 20.0.sp, + height: 20.0.sp, + ), + SizedBox(width: 4.0.sp), + Text( + '微信支付', + style: TextStyle( + color: const Color(0xFFF7FAFA), + fontSize: 14.0.sp, + ), + ), + ], + ), + ), + ], + ), + ), + GestureDetector( + onTap: () { + if (!isAgree) { + showOKToast('请先阅读并同意小票充值协议'); + return; + } + + if (Platform.isAndroid) { + String itemId = ''; + walletRechargeSelectItemBos.forEach((element) { + if (element.isSelected) { + itemId = element.id.toString(); + } + }); + startPayment(itemId); + } else { + iosPay(); + } + }, + child: Container( + height: 40.sp, + width: Get.width, + decoration: BoxDecoration( + gradient: AppColor.mainVerLinearGradient, + borderRadius: BorderRadius.circular(21.0), + ), + child: Center( + child: Text( + '立即充值', + style: TextStyle( + color: const Color(0xFFF7FAFA), + fontSize: 14.0.sp), + ), + ), + ), + ), + SizedBox(height: 16.0.sp), + + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + isAgree = !isAgree; + setState(() { + + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + isAgree ? + getMineImage("icon_pay_select"): getMineImage("icon_pay_is_no_select"), + width: 14.0.sp, + height: 14.0.sp, + ), + SizedBox(width: 4.0.sp), + + Text( + '阅读并同意', + style: TextStyle( + color: const Color(0xFFB7BECC), fontSize: 10.0.sp), + ), + GestureDetector( + onTap: () { + // navigateToPriceAgreement(); + }, + child: Text( + '《小票充值协议》', + style: TextStyle( + color: const Color(0xFF21BEAB), + fontSize: 10.0.sp), + ), + ), + ], + ), + ), + SizedBox(height: 10.0.sp), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '充值金额仅限APP使用,充值遇到问题?', + style: TextStyle( + color: const Color(0xFFB7BECC), fontSize: 10.0.sp), + ), + GestureDetector( + onTap: () async { + var con; + if(kDebugMode){ + con = V2TimConversation( + conversationID: "c2c_qpqz_dev_10_102", userID: "qpqz_dev_10_102", showName: "测试乐园客服", type: 1); + }else{ + con = V2TimConversation( + conversationID: "c2c_qpqz_prod_10_102", userID: "qpqz_prod_10_102", showName: "乐园客服", type: 1); + } + Get.toNamed(AppRoutes.Chat, arguments: con); + }, + child: Text( + '联系客服', + style: TextStyle( + color: const Color(0xFFEFD84E), + fontSize: 10.0.sp), + ), + ), + ], + ), + ], + ), + ), + + ] , + + ), + ); + } + + void iosPay() { + SmartDialog.showLoading(); + String itemId = ''; + String Id = ''; + walletRechargeSelectItemBos.forEach((element) { + if (element.isSelected) { + itemId = element.itemId!; + Id = element.id!.toString(); + } + }); + + IOSPayment.instance.iosPay(itemId,Id,4); + } + + Widget itemView(BuildContext context, AssetsDataDataPriceConfs item, int index) { + + + String iconIv = getMineImage('bi_icon${index+1}'); + return GestureDetector( + onTap: () { + setState(() { + walletRechargeSelectItemBos.asMap().forEach((key, value) { + value.isSelected = key == index; + }); + }); + }, + child: Container( + height: 49.sp, + margin: const EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + color: !item.isSelected + ? const Color(0xFF464556) + : const Color(0xFF464556), + borderRadius: BorderRadius.circular(6), + border: item.isSelected + ? Border.all(color: const Color(0xFF21BEAB), width: 1.sp) + : null, + ), + child: Container( + margin: EdgeInsets.only(left: 6.sp, right: 6.sp), + child: Row( + children: [ + Image.asset( + iconIv, // Replace this with the actual image path + width: 30.sp, + + ), + SizedBox(width: 8.sp), + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "${item.coin}小票", + style: TextStyle(color: Colors.white, fontSize: 14.sp), + ), + if (item.remark!.isNotEmpty) + Text( + item.remark!, + style: TextStyle( + color: const Color(0xFFEFD84E), fontSize: 10.0.sp), + ), + ],), + Expanded(child: Container()), + // To push the next widget to the right edge + Text( + '${item.amount}元', + style: TextStyle(color: Colors.white, fontSize: 14.sp), + ), + ], + ), + ), + )); + } + + void loadBalanceData() { + + } +} +/// +/// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/ +/// +class AssetsDataDataPriceConfs { +/* +{ + "amount": 0, + "coin": 0, + "id": 0, + "itemId": "", + "presentCoin": 0, + "presentWealthGrade": 0 +} +*/ + + int? amount; + int? coin; + int? id; + String? itemId; + String? remark; + bool isSelected = false; + int? presentCoin; + int? presentWealthGrade; + + AssetsDataDataPriceConfs({ + this.amount, + this.coin, + this.id, + this.itemId, + this.presentCoin, + this.presentWealthGrade, + }); + AssetsDataDataPriceConfs.fromJson(Map json) { + amount = json['amount']?.toInt(); + coin = json['coin']?.toInt(); + id = json['id']?.toInt(); + remark = json['remark'] ?? ''; + itemId = json['itemId']?.toString(); + presentCoin = json['presentCoin']?.toInt(); + presentWealthGrade = json['presentWealthGrade']?.toInt(); + } + Map toJson() { + final data = {}; + data['amount'] = amount; + data['coin'] = coin; + data['id'] = id; + data['itemId'] = itemId; + data['presentCoin'] = presentCoin; + data['presentWealthGrade'] = presentWealthGrade; + return data; + } +} + +class AssetsDataData { +/* +{ + "balance": 0, + "priceConfs": [ + { + "amount": 0, + "coin": 0, + "id": 0, + "itemId": "", + "presentCoin": 0, + "presentWealthGrade": 0 + } + ] +} +*/ + + int? balance; + List? priceConfs; + + AssetsDataData({ + this.balance, + this.priceConfs, + }); + AssetsDataData.fromJson(Map json) { + balance = json['balance']?.toInt(); + if (json['priceConfs'] != null) { + final v = json['priceConfs']; + final arr0 = []; + v.forEach((v) { + arr0.add(AssetsDataDataPriceConfs.fromJson(v)); + }); + priceConfs = arr0; + } + } + Map toJson() { + final data = {}; + data['balance'] = balance; + if (priceConfs != null) { + final v = priceConfs; + final arr0 = []; + v!.forEach((v) { + arr0.add(v!.toJson()); + }); + data['priceConfs'] = arr0; + } + return data; + } +} + +class AssetsData { +/* +{ + "code": 0, + "data": { + "balance": 0, + "priceConfs": [ + { + "amount": 0, + "coin": 0, + "id": 0, + "itemId": "", + "presentCoin": 0, + "presentWealthGrade": 0 + } + ] + }, + "msg": "" +} +*/ + + int? code; + AssetsDataData? data; + String? msg; + + AssetsData({ + this.code, + this.data, + this.msg, + }); + AssetsData.fromJson(Map json) { + code = json['code']?.toInt(); + data = (json['data'] != null) ? AssetsDataData.fromJson(json['data']) : null; + msg = json['msg']?.toString(); + } + Map toJson() { + final data = {}; + data['code'] = code; + if (data != null) { + data['data'] = this.data!.toJson(); + } + data['msg'] = msg; + return data; + } +} diff --git a/circle_app/lib/common/Widgets/base_tip_widget.dart b/circle_app/lib/common/Widgets/base_tip_widget.dart index ef06e71..92b0865 100644 --- a/circle_app/lib/common/Widgets/base_tip_widget.dart +++ b/circle_app/lib/common/Widgets/base_tip_widget.dart @@ -11,6 +11,7 @@ import 'package:get/get.dart'; import '../../network/api.dart'; import '../../network/dio_manager.dart'; import '../../util/PaymentUtils.dart'; +import 'RechargeScreenDialog.dart'; import 'open_vip_tip/logic.dart'; bool isZfbPrice = true; @@ -274,4 +275,14 @@ showJoinCiclePiker(String cicleId, String pirce, String oldPrice, int type, Future showAddWxPicker(bool isHaveWx,{bool isHidden = false, bool isWxHidden = false}) { return Get.bottomSheet(AddWxTip(isHaveWx,isHidden,isWxHidden),isScrollControlled: true,enableDrag: false); +} + + +Future showRechargeScreenDialog() { + return showDialog( + context: Get.context!, + builder: (BuildContext context) { + return RechargeScreenDialog(isShowBalance: true,); + }, + ); } \ No newline at end of file diff --git a/circle_app/lib/common/Widgets/circle_share.dart b/circle_app/lib/common/Widgets/circle_share.dart index 6ef3c9b..ad5e000 100644 --- a/circle_app/lib/common/Widgets/circle_share.dart +++ b/circle_app/lib/common/Widgets/circle_share.dart @@ -1,10 +1,13 @@ +import 'dart:convert'; import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:circle_app/app/circle/logic.dart'; import 'package:circle_app/app/invite/logic.dart'; import 'package:circle_app/app/minefragment/logic.dart'; +import 'package:circle_app/common/Widgets/follow_me_dialog.dart'; import 'package:circle_app/common/Widgets/text_more.dart'; +import 'package:circle_app/main.dart'; import 'package:circle_app/network/api.dart'; import 'package:circle_app/network/dio_manager.dart'; import 'package:circle_app/util/util.dart'; @@ -22,6 +25,8 @@ import 'package:fluwx/fluwx.dart' as fluwx; import 'package:path_provider/path_provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; +import '../../app/likelist/logic.dart'; + class CircleShare extends StatefulWidget { Circle bean; @@ -36,14 +41,17 @@ class CircleShare extends StatefulWidget { class _CircleShareState extends State { // TODO: add state variables and methods GlobalKey _globalKey = GlobalKey(); - - MinefragmentLogic logic = Get.find(); + List lists = []; + late MinefragmentLogic logic; @override void initState() { // TODO: implement initState super.initState(); + Get.lazyPut(() => MinefragmentLogic()); + logic = Get.find(); + loadFollowMeData(); loadInviteData(); } @@ -269,14 +277,57 @@ class _CircleShareState extends State { )) ), ), + SizedBox(height: 10.sp,), SafeArea( top: false, child: Container( - height: 164.sp, + height: lists.isNotEmpty ? 264.sp : 164.sp, width: Get.width, color: Color(0xFF292247), child: Column( children: [ + if (lists.isNotEmpty) + Container( + height: 100.sp, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemBuilder: (context,index) { + if (lists.length > 5 && index == 4) { + return GestureDetector( + onTap: () { + Get.bottomSheet(FollowMeDialog( bean: widget.bean,), isScrollControlled: true, + enableDrag: false); + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset(getCircleImage('share_more'),width: 51.sp,), + SizedBox(height: 4.sp,), + Text('更多',style: TextStyle(color: Colors.white,fontSize: 14.sp),) + ], + ), + ); + } + var info = lists[index]; + return GestureDetector( + onTap: () { + sendCircleCustomMsg( 'qpqz_dev_0_'+ info.user.id.toString(), jsonEncode(widget.bean.toJson()), '分享[${widget.bean.title}]'); + }, + behavior: HitTestBehavior.opaque, + child: Container( + width: Get.width / 5, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ClipOval(child: Image.network(info.user.avatar,width: 51.sp,height: 51.sp,fit: BoxFit.cover,),), + SizedBox(height: 4.sp,), + Text(info.user.nickname,style: TextStyle(color: Colors.white,fontSize: 14.sp),) + ], + ), + ), + ); + },itemCount: lists.length > 5 ? 5 : lists.length,), + ), Expanded( child: Container( padding: EdgeInsets.only( @@ -732,4 +783,17 @@ class _CircleShareState extends State { } } + + void loadFollowMeData() async { + var data = await DioManager.instance + .get(url: Api.fansList, params: {'page': 1,'page_size':6}); + var bean = BaseResponse.fromJson( + data, (data) => UserList.fromJson(data)); + if (bean.isSuccess()) { + lists.addAll(bean.data.lists); + } + setState(() { + + }); + } } diff --git a/circle_app/lib/common/Widgets/follow_me_dialog.dart b/circle_app/lib/common/Widgets/follow_me_dialog.dart new file mode 100644 index 0000000..c353ad9 --- /dev/null +++ b/circle_app/lib/common/Widgets/follow_me_dialog.dart @@ -0,0 +1,497 @@ +import 'dart:convert'; +import 'dart:ui'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; + +import '../../app/circle/logic.dart'; +import '../../app/likelist/logic.dart'; +import '../../app/minefragment/logic.dart'; +import '../../main.dart'; +import '../../network/api.dart'; +import '../../network/dio_manager.dart'; +import '../../router/app_routers.dart'; +import '../../util/util.dart'; +import '../colors/app_color.dart'; +import 'open_vip_tip/view.dart'; + +class FollowMeDialog extends StatefulWidget { + Circle bean; + FollowMeDialog({super.key,required this.bean}); + + + @override + _FollowMeDialogState createState() => new _FollowMeDialogState(); + +} + +class _FollowMeDialogState extends State { + // TODO: add state variables and methods + List lists = []; + bool isMore = true; + int page = 1; + bool isVip = false; + final RefreshController refreshController = RefreshController(); + + + @override + void initState() { + // TODO: implement initState + super.initState(); + loadMineInfo(); + loadData(); + } + + @override + Widget build(BuildContext context) { + // TODO: add widget build method + + + + return Scaffold( + backgroundColor: Colors.transparent, + body: Column( + children: [ + Container(height: Get.height * 0.33,width: Get.width,), + Expanded( + child: Container( + color: Colors.black, + child: Column( + children: [ + Container( + width: Get.width, + height: 36.sp, + child: Stack( + + alignment: Alignment.center, + children: [ + Text( + '喜欢我的', + style: TextStyle( + fontSize: 20.sp, + color: Colors.white + )), + Positioned( + right: 15.sp, + child: GestureDetector( + onTap: () { + Get.back(); + }, + child: Image.asset( + getCircleImage('close'), + width: 24.sp,), + )) + ], + ), + ), + Expanded(child: Stack( + + children: [ + SmartRefresher( + controller: refreshController, + // onRefresh: _onRefresh, + onLoading: _onLoading, + enablePullUp: true, + child: ListView.builder( + padding: EdgeInsets.zero, + itemCount: lists.length, + itemBuilder: (context, index) { + return ListItem(lists[index], index); + }, + ), + + ), + showGd() + ],)) + ], + ), + ), + ) + ], + ), + ); + } + + Widget showGd() { + double interval = 50; + List urlList = []; + + if (lists.length > 3) { + for (int i = 3; i < lists.length; i++) { + if (urlList.length < 3) { + print(lists[i].user.avatar); + urlList.add(lists[i].user.avatar); + } else { + break; + } + } + } + + List widgets = []; + + switch (urlList.length) { + case 0: + widgets.add(Positioned( + left: (Get.width / 2) - 40, + child: circleWidget(""), + )); + break; + case 1: + for (int i = 0; i < urlList.length; i++) { + var element = urlList[i]; +// double xOffset = interval * i + xOffsetBase; + double let = (Get.width / 2) - 60; + if (element == '') { + element = + 'https://i0.wp.com/picjumbo.com/wp-content/uploads/romantic-tropical-beach-with-villa-and-palms-during-beautiful-sunset-free-photo.jpg?w=600&quality=80'; + } + + widgets.add(Positioned( + left: let, + child: circleWidget(element), + )); + } + + widgets.add(Positioned( + left: (Get.width / 2) - 20, + child: circleWidget(""), + )); + break; + case 2: + double xOffsetBase = + (Get.width + interval * urlList.length - 60.0 * urlList.length) * + 0.25; + + for (int i = 0; i < urlList.length; i++) { + var element = urlList[i]; +// double xOffset = interval * i + xOffsetBase; + double let = ((Get.width / 2) - ((40 * urlList.length)) + (i * 40)); + if (element == '') { + element = + 'https://i0.wp.com/picjumbo.com/wp-content/uploads/romantic-tropical-beach-with-villa-and-palms-during-beautiful-sunset-free-photo.jpg?w=600&quality=80'; + } + widgets.add(Positioned( + left: let, + child: circleWidget(element), + )); + } + + double xOffset = interval * urlList.length + xOffsetBase; + widgets.add(Positioned( + left: xOffset, + child: circleWidget(""), + )); + break; + case 3: + // double xOffsetBase = (Get.width + interval * urlList.length - 60.0 * urlList.length) * 0.25; + + for (int i = 0; i < urlList.length; i++) { + switch (i) { + case 0: + if (urlList[i] == '') { + urlList[i] = + 'https://i0.wp.com/picjumbo.com/wp-content/uploads/romantic-tropical-beach-with-villa-and-palms-during-beautiful-sunset-free-photo.jpg?w=600&quality=80'; + } + widgets.add(Positioned( + left: (Get.width / 2) - 100, + child: circleWidget(urlList[i]), + )); + break; + case 1: + if (urlList[i] == '') { + urlList[i] = + 'https://i0.wp.com/picjumbo.com/wp-content/uploads/romantic-tropical-beach-with-villa-and-palms-during-beautiful-sunset-free-photo.jpg?w=600&quality=80'; + } + widgets.add(Positioned( + left: (Get.width / 2) - 60, + child: circleWidget(urlList[i]), + )); + break; + case 2: + if (urlList[i] == '') { + urlList[i] = + 'https://i0.wp.com/picjumbo.com/wp-content/uploads/romantic-tropical-beach-with-villa-and-palms-during-beautiful-sunset-free-photo.jpg?w=600&quality=80'; + } + widgets.add(Positioned( + left: (Get.width / 2) - 20, + child: circleWidget(urlList[i]), + )); + break; + } + } + widgets.add(Positioned( + left: (Get.width / 2) + 20, + child: circleWidget(""), + )); + + break; + } + + return isVip + ? Container() + : Positioned( + bottom: 150, + child: Container( + width: Get.width, + child: Column( + children: [ + SizedBox( + height: 140.sp, + width: Get.width, + child: Stack( + alignment: Alignment.centerLeft, + children: widgets, + ), + ), + Container( + margin: EdgeInsets.only(bottom: 40.sp), + child: Text( + "TA们也喜欢你哦 \n" + "成为会员查看所有圈友信息", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 15.sp, + ), + ), + ), + GestureDetector( + onTap: () { + showRechargeDialog(); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17), + gradient: AppColor.mainVerLinearGradient, + ), + padding: EdgeInsets.symmetric( + vertical: 10.sp, + horizontal: 55.sp, + ), + child: Text( + "开通会员查看更多访客", + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + ), + ), + ), + ), + ], + ), + ), + ); + } + + circleWidget(String url, {double width = 80}) { + return GestureDetector( + onTap: () { + // openvi(); + }, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset( + getCircleImage('more'), + width: width.sp, + height: width.sp, + ), + url != null && url.contains("http") + ? ClipOval( + child: CachedNetworkImage( + imageUrl: url, + width: (width - 1).sp, + height: (width - 1).sp, + fit: BoxFit.cover, + ), + ) + : Text( + url, + style: TextStyle(color: Color(0xffF756FF), fontSize: 12.sp), + ) + ], + )); + } + + Widget ListItem(UserListItem item, int index) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + if (isVip || index < 3) { + sendCircleCustomMsg( 'qpqz_dev_0_'+ item.user.id.toString(), jsonEncode(widget.bean.toJson()), '分享[${widget.bean.title}]'); + // Get.toNamed(AppRoutes.UserInfoActivity, + // arguments: item.user.id.toString()); + } + }, + child: ImageFiltered( + imageFilter: ImageFilter.blur( + sigmaX: (isVip || index < 3) ? 0 : 5, + sigmaY: (isVip || index < 3) ? 0 : 5, + ), + + child: Container( + margin: EdgeInsets.only(bottom: 21.sp), + child: Row( + children: [ + Stack( + children: [ + ClipOval( + child: GestureDetector( + onTap: () { + var imgList = []; + imgList.add(item.user.avatar); + Get.toNamed(AppRoutes.Swiper, + arguments: {'imaglist': imgList, 'index': 0}); + }, + child: CachedNetworkImage( + fit: BoxFit.cover, + imageUrl: item.user.avatarThumb, + width: 53.sp, + height: 53.sp, + ), + ), + ), + Positioned( + right: 0.sp, + left: 0.sp, + bottom: 0.sp, + child: item.user.vip != 0 + ? Image( + image: AssetImage(getBaseImage( + item.user.vip == 1 ? "vip" : 'year_vip')), + width: 44.sp, + height: 18.sp, + ) + : Container(), + ) + ], + ), + SizedBox(width: 10.sp), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + item.user.nickname, + style: const TextStyle( + color: Colors.white70, + fontSize: 14, + fontWeight: FontWeight.bold), + ), + SizedBox(width: 4.sp), + // SizedBox(height: 8.sp), + _buildInfoRow(item), + // Placeholder image + ], + ), + SizedBox(height: 8.sp), + SizedBox( + width: 200.sp, + child: Text( + item.user.signature, + overflow: TextOverflow.ellipsis, // 超出部分使用省略号表示 + maxLines: 1, + style: TextStyle( + fontSize: 12.sp, color: const Color(0xFFB7BECC)), + ), + ), + ], + ), + // Pla + const Spacer(), + + ], + ), + ), + ), + ); + } + + Widget _buildInfoRow(UserListItem userInfoBean) { + String ageMsg = getAgeCOntent( + userInfoBean.user.gender, + userInfoBean.user.age, + userInfoBean.user.role, + userInfoBean.user.orientation); + return Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17.sp), + gradient: const LinearGradient( + colors: [ + Color.fromRGBO(141, 255, 248, 1.0), + Color.fromRGBO(181, 211, 255, 1.0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.only( + top: 2.sp, bottom: 2.sp, left: 10.sp, right: 10.sp), + child: Text( + ageMsg, + style: TextStyle( + color: Colors.black, + fontSize: 10.sp, + ), + ), + ), + SizedBox(width: 6.sp), + ], + ); + } + + _onLoading() { + if (isMore) { + page = page + 1; + loadData(); + } + } + + showRechargeDialog() async { + Get.bottomSheet( + Scaffold( + backgroundColor: Colors.transparent, + body: Open_vip_tipPage(false), + ), + isScrollControlled: true, + enableDrag: false).then((value) { + loadMineInfo(); + }); + } + + void loadData() async { + var data = await DioManager.instance + .get(url: Api.fansList, params: {'page': page,'page_size':6}); + var bean = BaseResponse.fromJson( + data, (data) => UserList.fromJson(data)); + if (bean.isSuccess()) { + List data = bean.data.lists; + if (data.isNotEmpty) { + lists.addAll(bean.data.lists); + refreshController.loadComplete(); + } else { + isMore = false; + refreshController.loadNoData(); + } + + } + setState(() { + + }); + } + + void loadMineInfo() async { + var data = await DioManager.instance.get(url: Api.getUserMine); + var bean = BaseResponse.fromJson( + data, (data) => MineResponseBean.fromJson(data)); + if (bean.isSuccess()) { + isVip = bean.data.user.vip > 0; + } + } +} diff --git a/circle_app/lib/main.dart b/circle_app/lib/main.dart index f8c0b99..756ea5a 100644 --- a/circle_app/lib/main.dart +++ b/circle_app/lib/main.dart @@ -279,7 +279,7 @@ sendTextMsg(String userId, {String content = '看看这次缘分匹配到哪位 // } } -//发送自定义消息 +//发送卡片自定义消息 sendCustomMsg(String userId, String data, String desc) async { // 创建自定义消息 V2TimValueCallback createCustomMessageRes = @@ -311,6 +311,39 @@ sendCustomMsg(String userId, String data, String desc) async { } } +//发送圈子自定义消息 +sendCircleCustomMsg(String userId, String data, String desc) async { + // 创建自定义消息 + V2TimValueCallback createCustomMessageRes = + await TencentImSDKPlugin.v2TIMManager + .getMessageManager() + .createCustomMessage( + data: data, + desc: desc, + extension: 'circleData', + ); + if (createCustomMessageRes.code == 0) { + String? id = createCustomMessageRes.data?.id; + // 发送自定义消息 + //EventBusManager.fire(SendCoustomMessage(createCustomMessageRes)); + + // 在sendMessage时,若只填写receiver则发个人用户单聊消息 + // 若只填写groupID则发群组消息 + // 若填写了receiver与groupID则发群内的个人用户,消息在群聊中显示,只有指定receiver能看见 + V2TimValueCallback sendMessageRes = await TencentImSDKPlugin + .v2TIMManager + .getMessageManager() + .sendMessage(id: id!, receiver: userId, groupID: ''); + if (sendMessageRes.code == 0) { + // 发送成功 + sendMessageRes.data?.customElem?.data; //自定义data + sendMessageRes.data?.customElem?.desc; //自定义desc + sendMessageRes.data?.customElem?.extension; //自定义extension + showOKToast('发送成功'); + } + } +} + class MyApp extends StatefulWidget { const MyApp({super.key}); diff --git a/circle_app/lib/network/api.dart b/circle_app/lib/network/api.dart index 2a36981..ef0f4fc 100644 --- a/circle_app/lib/network/api.dart +++ b/circle_app/lib/network/api.dart @@ -1,10 +1,10 @@ class Api { - static const baseUrl = 'https://leyuan666.com/zuul-service/'; + // static const baseUrl = 'https://leyuan666.com/zuul-service/'; - // static const baseUrl = 'http://192.168.3.55:2000/'; + static const baseUrl = 'http://192.168.3.55:2000/'; // 获取验证码 @@ -310,5 +310,22 @@ class Api { //是否显示好评反馈 static const showPositiveFeedBack = '/up-service/showPositiveFeedBack'; + //钱包充值选项查询 + static const walletRechargeSelectItem = '/mall-service/wallet/walletRechargeConfig'; + //用户资产 + static const userAsset = '/mall-service/wallet/userAsset'; + + //账单 + static const userBill = '/mall-service/wallet/userBill'; + + static const rechargeOrder = '/mall-service/wallet/walletRechargeConfig'; + + static const sendGift = '/mall-service/gift/sendGift'; + + //礼物列表 + static const giftList = '/mall-service/gift/giftMall'; + + //礼物馆 + static const giftHall = '/mall-service/gift/giftHall/'; } \ No newline at end of file diff --git a/circle_app/lib/router/app_pages.dart b/circle_app/lib/router/app_pages.dart index 25d554c..9d6d47e 100644 --- a/circle_app/lib/router/app_pages.dart +++ b/circle_app/lib/router/app_pages.dart @@ -2,6 +2,8 @@ import 'package:circle_app/app/aboutapp/binding.dart'; import 'package:circle_app/app/aboutapp/view.dart'; import 'package:circle_app/app/account/binding.dart'; import 'package:circle_app/app/account/view.dart'; +import 'package:circle_app/app/bill/binding.dart'; +import 'package:circle_app/app/bill/view.dart'; import 'package:circle_app/app/bindmail/binding.dart'; import 'package:circle_app/app/bindmail/view.dart'; import 'package:circle_app/app/blacklist/binding.dart'; @@ -17,6 +19,8 @@ import 'package:circle_app/app/feedback/binding.dart'; import 'package:circle_app/app/feedback/view.dart'; import 'package:circle_app/app/friendslist/binding.dart'; import 'package:circle_app/app/friendslist/view.dart'; +import 'package:circle_app/app/gift_shop/binding.dart'; +import 'package:circle_app/app/gift_shop/view.dart'; import 'package:circle_app/app/help/binding.dart'; import 'package:circle_app/app/help/view.dart'; import 'package:circle_app/app/home/binding.dart'; @@ -32,6 +36,7 @@ import 'package:circle_app/app/msg/binding.dart'; import 'package:circle_app/app/msg/sys_notify_list/binding.dart'; import 'package:circle_app/app/msg/sys_notify_list/view.dart'; import 'package:circle_app/app/msg/view.dart'; +import 'package:circle_app/app/my_assets/view.dart'; import 'package:circle_app/app/my_circle/binding.dart'; import 'package:circle_app/app/my_circle/view.dart'; import 'package:circle_app/app/myfeedbacklist/binding.dart'; @@ -73,6 +78,7 @@ import '../app/externalshare/binding.dart'; import '../app/externalshare/view.dart'; import '../app/good_reviews/binding.dart'; import '../app/good_reviews/view.dart'; +import '../app/my_assets/binding.dart'; import '../app/privacy/binding.dart'; import '../app/splash/view.dart'; import '../app/visitorlist/binding.dart'; @@ -252,5 +258,13 @@ class AppPages { page: () => Good_reviewsPage(), binding: Good_reviewsBinding(), ), + GetPage(name: AppRoutes.MyAssets, page: () => My_assetsPage(), + binding: My_assetsBinding(),), + GetPage(name: AppRoutes.BillActivity, page: () => BillPage(), + binding: BillBinding(),), + GetPage(name: AppRoutes.GiftShopPage, page: () => Gift_shopPage(), + binding: Gift_shopBinding(),) + + ]; } diff --git a/circle_app/lib/router/app_routers.dart b/circle_app/lib/router/app_routers.dart index a79c423..2de5c9c 100644 --- a/circle_app/lib/router/app_routers.dart +++ b/circle_app/lib/router/app_routers.dart @@ -45,6 +45,12 @@ abstract class AppRoutes { static const Good_Reviews = '/Good_Reviews'; + static const MyAssets = '/MyAssets'; + + static const BillActivity = '/BillActivity'; + + static const GiftShopPage = '/GiftShopPage'; + } \ No newline at end of file diff --git a/circle_app/lib/util/eventBus.dart b/circle_app/lib/util/eventBus.dart index 2448e13..5a76b4d 100644 --- a/circle_app/lib/util/eventBus.dart +++ b/circle_app/lib/util/eventBus.dart @@ -28,6 +28,10 @@ class EventBusManager { } +class AssestEvent { +} + + class CommentVipEvent { int vip = 0; diff --git a/circle_app/lib/util/paymentUtil.dart b/circle_app/lib/util/paymentUtil.dart index dd650bb..e26539d 100644 --- a/circle_app/lib/util/paymentUtil.dart +++ b/circle_app/lib/util/paymentUtil.dart @@ -37,7 +37,7 @@ class IOSPayment { // iOS订阅监听 StreamSubscription>? subscription; - //1圈子 2会员 3解锁微信 + //1圈子 2会员 3解锁微信 4充值 int type = 0; //可以为解锁圈子ID、会员标识ID String typeId = ''; @@ -88,6 +88,8 @@ class IOSPayment { if (type == 3) { params['target_id'] = target_id; + } else if (target_id.isNotEmpty) { + params['target_id'] = target_id; } var result = await DioManager.getInstance() @@ -96,7 +98,9 @@ class IOSPayment { if (result['code'] == 200) { try { - Get.back(); + if (type != 4) { + Get.back(); + } } catch (e) {} if (type == 1) { @@ -112,8 +116,16 @@ class IOSPayment { logic.update(); } } else if (type == 2) { - showOKToast('开通会员成功'); - EventBusManager.fire(CommentVipEvent(1)); + if (target_id.isNotEmpty) { + showOKToast('赠送会员成功'); + target_id = ''; + } else { + showOKToast('开通会员成功'); + EventBusManager.fire(CommentVipEvent(1)); + } + } else if (type == 4) { + showOKToast('充值成功'); + EventBusManager.fire(AssestEvent()); } else { showOKToast('解锁微信号成功'); unLockWxSuccessResult(target_id); diff --git a/circle_app/lib/util/util.dart b/circle_app/lib/util/util.dart index 003c705..ee9cbed 100644 --- a/circle_app/lib/util/util.dart +++ b/circle_app/lib/util/util.dart @@ -313,7 +313,7 @@ class CustomLoadFooter extends StatelessWidget { canLoadingText: "松手开始加载数据", loadingText: "正在加载...", idleText: "上拉加载更多", - noDataText: "只展示推荐的哦~", + noDataText: "到底了~", failedText: "加载失败", ); }