Browse Source
feat(live): 添加礼物产品功能并实现直播间结束页面
feat(live): 添加礼物产品功能并实现直播间结束页面
- 新增礼物产品模型 GiftProductModel - 在 RoomController 中集成礼物产品列表加载逻辑 - 实现直播间结束页面 LiveEndPage - 添加获取礼物产品列表的 API 接口 - 更新网络服务以支持礼物产品相关请求ios
6 changed files with 343 additions and 0 deletions
Split View
Diff Options
-
22lib/controller/discover/room_controller.dart
-
66lib/model/live/gift_product_model.dart
-
2lib/network/api_urls.dart
-
5lib/network/rtc_api.dart
-
41lib/network/rtc_api.g.dart
-
207lib/pages/discover/live_end_page.dart
@ -0,0 +1,66 @@ |
|||
/// 礼物产品模型 |
|||
class GiftProductModel { |
|||
final String productId; |
|||
final String productSpecId; |
|||
final int mainCategory; |
|||
final int subCategory; |
|||
final String productTitle; |
|||
final String productDesc; |
|||
final String? detailDesc; |
|||
final double unitOriginalPrice; |
|||
final double unitSellingPrice; |
|||
final String mainPic; |
|||
final String svgaFile; |
|||
|
|||
GiftProductModel({ |
|||
required this.productId, |
|||
required this.productSpecId, |
|||
required this.mainCategory, |
|||
required this.subCategory, |
|||
required this.productTitle, |
|||
required this.productDesc, |
|||
this.detailDesc, |
|||
required this.unitOriginalPrice, |
|||
required this.unitSellingPrice, |
|||
required this.mainPic, |
|||
required this.svgaFile, |
|||
}); |
|||
|
|||
factory GiftProductModel.fromJson(Map<String, dynamic> json) { |
|||
return GiftProductModel( |
|||
productId: json['productId']?.toString() ?? '', |
|||
productSpecId: json['productSpecId']?.toString() ?? '', |
|||
mainCategory: json['mainCategory'] as int? ?? 0, |
|||
subCategory: json['subCategory'] as int? ?? 0, |
|||
productTitle: json['productTitle']?.toString() ?? '', |
|||
productDesc: json['productDesc']?.toString() ?? '', |
|||
detailDesc: json['detailDesc']?.toString(), |
|||
unitOriginalPrice: (json['unitOriginalPrice'] as num?)?.toDouble() ?? 0.0, |
|||
unitSellingPrice: (json['unitSellingPrice'] as num?)?.toDouble() ?? 0.0, |
|||
mainPic: json['mainPic']?.toString() ?? '', |
|||
svgaFile: json['svgaFile']?.toString() ?? '', |
|||
); |
|||
} |
|||
|
|||
Map<String, dynamic> toJson() { |
|||
return { |
|||
'productId': productId, |
|||
'productSpecId': productSpecId, |
|||
'mainCategory': mainCategory, |
|||
'subCategory': subCategory, |
|||
'productTitle': productTitle, |
|||
'productDesc': productDesc, |
|||
'detailDesc': detailDesc, |
|||
'unitOriginalPrice': unitOriginalPrice, |
|||
'unitSellingPrice': unitSellingPrice, |
|||
'mainPic': mainPic, |
|||
'svgaFile': svgaFile, |
|||
}; |
|||
} |
|||
|
|||
@override |
|||
String toString() { |
|||
return 'GiftProductModel(productId: $productId, productTitle: $productTitle, unitSellingPrice: $unitSellingPrice)'; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,207 @@ |
|||
import 'package:cached_network_image/cached_network_image.dart'; |
|||
import 'package:dating_touchme_app/controller/discover/room_controller.dart'; |
|||
import 'package:dating_touchme_app/extension/ex_widget.dart'; |
|||
import 'package:dating_touchme_app/generated/assets.dart'; |
|||
import 'package:dating_touchme_app/pages/main/main_page.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
class LiveEndPage extends StatelessWidget { |
|||
const LiveEndPage({super.key}); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
final roomController = Get.find<RoomController>(); |
|||
final anchorInfo = roomController.rtcChannelDetail.value?.anchorInfo; |
|||
|
|||
return Scaffold( |
|||
body: Container( |
|||
decoration: BoxDecoration( |
|||
gradient: LinearGradient( |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
colors: [ |
|||
const Color.fromRGBO(19, 16, 47, 1), |
|||
const Color.fromRGBO(19, 16, 47, 1).withOpacity(0.8), |
|||
], |
|||
), |
|||
), |
|||
child: SafeArea( |
|||
child: Column( |
|||
children: [ |
|||
// 顶部返回按钮 |
|||
Padding( |
|||
padding: EdgeInsets.only(left: 16.w, top: 10.w), |
|||
child: Align( |
|||
alignment: Alignment.centerLeft, |
|||
child: IconButton( |
|||
icon: Icon( |
|||
Icons.arrow_back_ios, |
|||
color: Colors.white, |
|||
size: 20.w, |
|||
), |
|||
onPressed: () { |
|||
Get.back(); |
|||
}, |
|||
), |
|||
), |
|||
), |
|||
// 主要内容区域 |
|||
Expanded( |
|||
child: Column( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
// 头像 |
|||
Container( |
|||
width: 120.w, |
|||
height: 120.w, |
|||
decoration: BoxDecoration( |
|||
shape: BoxShape.circle, |
|||
border: Border.all( |
|||
color: Colors.white.withOpacity(0.3), |
|||
width: 2.w, |
|||
), |
|||
), |
|||
child: ClipOval( |
|||
child: anchorInfo?.profilePhoto != null && |
|||
anchorInfo!.profilePhoto.isNotEmpty |
|||
? CachedNetworkImage( |
|||
imageUrl: |
|||
"${anchorInfo.profilePhoto}?x-oss-process=image/format,webp/resize,w_240", |
|||
width: 120.w, |
|||
height: 120.w, |
|||
fit: BoxFit.cover, |
|||
placeholder: (context, url) => Container( |
|||
color: Colors.grey.withOpacity(0.3), |
|||
child: Center( |
|||
child: CircularProgressIndicator( |
|||
strokeWidth: 2.w, |
|||
color: Colors.white.withOpacity(0.5), |
|||
), |
|||
), |
|||
), |
|||
errorWidget: (context, url, error) => |
|||
Image.asset( |
|||
Assets.imagesUserAvatar, |
|||
width: 120.w, |
|||
height: 120.w, |
|||
fit: BoxFit.cover, |
|||
), |
|||
) |
|||
: Image.asset( |
|||
Assets.imagesUserAvatar, |
|||
width: 120.w, |
|||
height: 120.w, |
|||
fit: BoxFit.cover, |
|||
), |
|||
), |
|||
), |
|||
SizedBox(height: 20.w), |
|||
// 用户名和关注按钮 |
|||
Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
crossAxisAlignment: CrossAxisAlignment.center, |
|||
children: [ |
|||
Text( |
|||
anchorInfo?.nickName ?? '用户', |
|||
style: TextStyle( |
|||
fontSize: 18.w, |
|||
fontWeight: FontWeight.w500, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
SizedBox(width: 12.w), |
|||
// 关注按钮 |
|||
Container( |
|||
padding: EdgeInsets.symmetric( |
|||
horizontal: 16.w, |
|||
vertical: 6.w, |
|||
), |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(20.w), |
|||
border: Border.all( |
|||
color: Colors.white, |
|||
width: 1.w, |
|||
), |
|||
), |
|||
child: Text( |
|||
'关注', |
|||
style: TextStyle( |
|||
fontSize: 14.w, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
).onTap(() { |
|||
// TODO: 实现关注功能 |
|||
print('点击关注'); |
|||
}), |
|||
], |
|||
), |
|||
SizedBox(height: 60.w), |
|||
// 状态消息(带横线) |
|||
Row( |
|||
children: [ |
|||
Expanded( |
|||
child: Container( |
|||
height: 1.w, |
|||
color: Colors.white.withOpacity(0.3), |
|||
), |
|||
), |
|||
Padding( |
|||
padding: EdgeInsets.symmetric(horizontal: 16.w), |
|||
child: Text( |
|||
'当前相亲已结束', |
|||
style: TextStyle( |
|||
fontSize: 14.w, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
), |
|||
Expanded( |
|||
child: Container( |
|||
height: 1.w, |
|||
color: Colors.white.withOpacity(0.3), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
], |
|||
), |
|||
), |
|||
// 底部返回首页按钮 |
|||
Padding( |
|||
padding: EdgeInsets.only( |
|||
left: 20.w, |
|||
right: 20.w, |
|||
bottom: 40.w + MediaQuery.of(context).padding.bottom, |
|||
), |
|||
child: Container( |
|||
width: double.infinity, |
|||
height: 50.w, |
|||
decoration: BoxDecoration( |
|||
borderRadius: BorderRadius.circular(25.w), |
|||
color: const Color.fromRGBO(108, 105, 244, 1), |
|||
), |
|||
child: Center( |
|||
child: Text( |
|||
'返回首页', |
|||
style: TextStyle( |
|||
fontSize: 16.w, |
|||
fontWeight: FontWeight.w500, |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
), |
|||
).onTap(() { |
|||
Get.offAll(() => const MainPage()); |
|||
}), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
|
|||
Write
Preview
Loading…
Cancel
Save