diff --git a/assets/images/ic_memory.png b/assets/images/ic_memory.png index 1aea22c..587a366 100644 Binary files a/assets/images/ic_memory.png and b/assets/images/ic_memory.png differ diff --git a/assets/images/ic_memory_p.png b/assets/images/ic_memory_p.png deleted file mode 100644 index bab3f84..0000000 Binary files a/assets/images/ic_memory_p.png and /dev/null differ diff --git a/assets/images/ic_more_no.png b/assets/images/ic_more_no.png new file mode 100644 index 0000000..03d99b8 Binary files /dev/null and b/assets/images/ic_more_no.png differ diff --git a/lib/beans/account_bean.dart b/lib/beans/account_bean.dart new file mode 100644 index 0000000..0c79550 --- /dev/null +++ b/lib/beans/account_bean.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:talk/beans/recharge_bean.dart'; + +part 'account_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class AccountBean { + int? currency; + List? currencyRechargeList; + + AccountBean(this.currency, this.currencyRechargeList); + + factory AccountBean.fromJson(Map json) => _$AccountBeanFromJson(json); + + Map toJson() => _$AccountBeanToJson(this); +} diff --git a/lib/beans/mall_bean.dart b/lib/beans/mall_bean.dart new file mode 100644 index 0000000..02e3216 --- /dev/null +++ b/lib/beans/mall_bean.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:talk/beans/mall_item_bean.dart'; + +part 'mall_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class MallBean { + List? mall; + List? purchased; + + MallBean(this.mall, this.purchased); + + factory MallBean.fromJson(Map json) => _$MallBeanFromJson(json); + + Map toJson() => _$MallBeanToJson(this); +} diff --git a/lib/beans/mall_item_bean.dart b/lib/beans/mall_item_bean.dart new file mode 100644 index 0000000..78cf481 --- /dev/null +++ b/lib/beans/mall_item_bean.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'mall_item_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class MallItemBean { + int? propId; + String? propName; + int? propCount; + int? propType; + int? price; + int? priceType; + String? imgUrl; + + MallItemBean(this.propId, this.propName, this.propCount, this.propType, this.price, this.priceType, this.imgUrl); + + factory MallItemBean.fromJson(Map json) => _$MallItemBeanFromJson(json); + + Map toJson() => _$MallItemBeanToJson(this); +} diff --git a/lib/beans/me_character_info_bean.dart b/lib/beans/me_character_info_bean.dart new file mode 100644 index 0000000..966758c --- /dev/null +++ b/lib/beans/me_character_info_bean.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'me_character_info_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class MeCharacterInfoBean { + int? characterId; + String? characterName; + String? bgImage; + + + MeCharacterInfoBean(this.characterId, this.characterName, this.bgImage); + + factory MeCharacterInfoBean.fromJson(Map json) => _$MeCharacterInfoBeanFromJson(json); + + Map toJson() => _$MeCharacterInfoBeanToJson(this); +} diff --git a/lib/beans/recharge_bean.dart b/lib/beans/recharge_bean.dart new file mode 100644 index 0000000..273b18e --- /dev/null +++ b/lib/beans/recharge_bean.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'recharge_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class RechargeBean { + int? id; + int? currencyCount; + int? price; + String? discount; + int? currencyType; + String? imgUrl; + + RechargeBean(this.id, this.currencyCount, this.price, this.discount, this.currencyType, this.imgUrl); + + factory RechargeBean.fromJson(Map json) => _$RechargeBeanFromJson(json); + + Map toJson() => _$RechargeBeanToJson(this); +} diff --git a/lib/beans/transaction_records_bean.dart b/lib/beans/transaction_records_bean.dart new file mode 100644 index 0000000..4d7bdf9 --- /dev/null +++ b/lib/beans/transaction_records_bean.dart @@ -0,0 +1,19 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'transaction_records_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class TransactionRecordsBean { + String? transactionContent; + String? transactionTime; + int? transactionAmount; + int? transactionType; + int? currencyType; + + TransactionRecordsBean(this.transactionContent, this.transactionTime, this.transactionAmount, this.transactionType, this.currencyType); + + factory TransactionRecordsBean.fromJson(Map json) => _$TransactionRecordsBeanFromJson(json); + + Map toJson() => _$TransactionRecordsBeanToJson(this); +} diff --git a/lib/beans/user_info_bean.dart b/lib/beans/user_info_bean.dart new file mode 100644 index 0000000..933c14f --- /dev/null +++ b/lib/beans/user_info_bean.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'me_character_info_bean.dart'; + +part 'user_info_bean.g.dart'; + +///标签 +@JsonSerializable(explicitToJson: true) +class UserInfoBean { + int? currency; + String? userIconUrl; + int? userId; + String? nickName; + int? remainingChatCount; + List? characterInfo; + int? memoryCardCount; + + UserInfoBean(this.currency, this.userIconUrl, this.userId, this.nickName, this.remainingChatCount, this.characterInfo, this.memoryCardCount); + + factory UserInfoBean.fromJson(Map json) => _$UserInfoBeanFromJson(json); + + Map toJson() => _$UserInfoBeanToJson(this); +} diff --git a/lib/main.dart b/lib/main.dart index 74a4c1a..d425882 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,11 +7,10 @@ import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:talk/tools/home_page.dart'; import 'package:talk/tools/login/login_page.dart'; import 'package:talk/tools/me/setting_page.dart'; +import 'package:talk/tools/search/search_page.dart'; import 'package:talk/tools/shop/account_page.dart'; import 'package:talk/tools/shop/problem_page.dart'; import 'package:talk/tools/shop/shop_page.dart'; -import 'package:talk/tools/shop/transaction_page.dart'; -import 'package:talk/tools/search/search_page.dart'; import 'package:talk/tools/start_page.dart'; import 'common/Global.dart'; @@ -58,7 +57,6 @@ class _ChatAppState extends State { '/SearchPage': (BuildContext context) => const SearchPage(), '/LoginPage': (BuildContext context) => const LoginPage(), '/AccountPage': (BuildContext context) => const AccountPage(), - '/TransactionPage': (BuildContext context) => const TransactionPage(), '/ProblemPage': (BuildContext context) => const ProblemPage(), '/ShopPage': (BuildContext context) => const ShopPage(), '/SettingPage': (BuildContext context) => const SettingPage(), diff --git a/lib/network/NetworkConfig.dart b/lib/network/NetworkConfig.dart index 00bec35..1a453dc 100644 --- a/lib/network/NetworkConfig.dart +++ b/lib/network/NetworkConfig.dart @@ -49,6 +49,14 @@ class NetworkConfig { static const String getCategoryFindList = "api/Category/GetCategoryFindList"; //发现-第一页固定内容 + static const String getUserInfo = "api/Account/GetUserInfo"; //获取用户信息 + + static const String getMyAccount = "api/Account/GetMyAccount"; //我的账户 + + static const String getTransactionRecords = "api/Account/GetTransactionRecords"; //交易记录 + + static const String getMallItem = "api/Account/GetMallItem"; //货币商城 + static const String chat = "/v1/chat/completions"; //聊天 static const String uploadImg = "/upload/image"; //审核模式上传图片 diff --git a/lib/tools/chat/chat_page.dart b/lib/tools/chat/chat_page.dart index 3b603e4..81d23ee 100644 --- a/lib/tools/chat/chat_page.dart +++ b/lib/tools/chat/chat_page.dart @@ -224,21 +224,20 @@ class _ChatPageState extends State { child: Stack( alignment: Alignment.center, children: [ - Positioned( - left: 105, - child: Text( - "+1", - style: TextStyle(color: Color(0xFFF14476), fontSize: 10), - )), + // Positioned( + // left: 105, + // child: Text( + // "+1", + // style: TextStyle(color: Color(0xFFF14476), fontSize: 10), + // )), Positioned( left: 0, child: Container( - width: 101, height: 30, decoration: BoxDecoration(color: Color(0x33000000), borderRadius: BorderRadius.all(Radius.circular(14))), child: Row( crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, children: [ ///AI头像 GestureDetector( @@ -250,16 +249,20 @@ class _ChatPageState extends State { }, child: Container( margin: EdgeInsets.only(left: 2), - child: Image( - width: 23, - image: AssetImage('assets/images/img_head2.png'), + child: ClipOval( + child: CachedNetworkImage( + width: 23, + height: 23, + imageUrl: '${characterInfoBean?.icon}', + errorWidget: (context, url, error) => const Icon(Icons.error), + ), ), ), ), ///AI名 Container( - margin: EdgeInsets.only(left: 5), + margin: EdgeInsets.only(left: 5, right: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -284,36 +287,36 @@ class _ChatPageState extends State { ), ///心动值 - Container( - margin: EdgeInsets.only(left: 6, right: 6), - child: GestureDetector( - onTap: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => ChatPage( - // id: '123', - // )), - // ); - }, - child: Stack( - alignment: Alignment.center, - children: [ - Image( - width: 24, - height: 21, - image: AssetImage('assets/images/ic_beckoning.png'), - ), - characterInfoBean != null - ? Text( - characterInfoBean!.intimacy.toString(), - style: TextStyle(fontSize: 8, color: Colors.white), - ) - : Container(), - ], - ), - ), - ), + // Container( + // margin: EdgeInsets.only(left: 6, right: 6), + // child: GestureDetector( + // onTap: () { + // // Navigator.push( + // // context, + // // MaterialPageRoute( + // // builder: (context) => ChatPage( + // // id: '123', + // // )), + // // ); + // }, + // child: Stack( + // alignment: Alignment.center, + // children: [ + // Image( + // width: 24, + // height: 21, + // image: AssetImage('assets/images/ic_beckoning.png'), + // ), + // characterInfoBean != null + // ? Text( + // characterInfoBean!.intimacy.toString(), + // style: TextStyle(fontSize: 8, color: Colors.white), + // ) + // : Container(), + // ], + // ), + // ), + // ), ], ), ), @@ -350,17 +353,21 @@ class _ChatPageState extends State { ///聊天列表 Expanded( - child: ListView.builder( - controller: _scrollController, - itemCount: chatList.length, - itemBuilder: (BuildContext context, int index) { - return _item(index); - })), - Container( - alignment: Alignment.centerLeft, - margin: EdgeInsets.only(left: 16, bottom: 3), - child: Image(width: 63, height: 18, image: AssetImage('assets/images/ic_memory.png')), - ), + child: Align( + alignment: Alignment.bottomCenter, + child: ListView.builder( + shrinkWrap: true, + controller: _scrollController, + itemCount: chatList.length, + itemBuilder: (BuildContext context, int index) { + return _item(index); + }), + )), + // Container( + // alignment: Alignment.centerLeft, + // margin: EdgeInsets.only(left: 16, bottom: 3), + // child: Image(width: 63, height: 18, image: AssetImage('assets/images/ic_memory.png')), + // ), ///输入 功能 Container( @@ -512,6 +519,31 @@ class _ChatPageState extends State { ), ), ), + Container( + margin: EdgeInsets.only(left: 23), + child: GestureDetector( + onTap: () { + setState(() { + isMore = false; + }); + // EasyLoading.show(status: 'loading...'); + // _viewmodel.delChat(widget.characterId); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image(width: 26, height: 26, image: AssetImage('assets/images/ic_memory.png')), + Container( + margin: EdgeInsets.only(top: 9), + child: Text( + '记忆提升', + style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)), + ), + ), + ], + ), + ), + ), ], ), ) @@ -519,16 +551,6 @@ class _ChatPageState extends State { ], ), ), - - ///记忆提升中 - Positioned( - top: 100, - left: 16, - child: Image( - width: 47, - height: 12, - image: AssetImage('assets/images/ic_memory_p.png'), - )), ], ), ); diff --git a/lib/tools/find/multiplex_page.dart b/lib/tools/find/multiplex_page.dart index 1259d52..63c2e87 100644 --- a/lib/tools/find/multiplex_page.dart +++ b/lib/tools/find/multiplex_page.dart @@ -94,12 +94,17 @@ class _MultiplexPageState extends State { children: [ Positioned( left: 7, - child: CachedNetworkImage( - width: 83, - height: 115, - imageUrl: data.iconImage!, - errorWidget: (context, url, error) => const Icon(Icons.error), - ), + child: + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(15)), + child: CachedNetworkImage( + width: 83, + height: 115, + fit: BoxFit.cover, + imageUrl: data.iconImage!, + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), ), Positioned( left: 101, diff --git a/lib/tools/find/recommend_page.dart b/lib/tools/find/recommend_page.dart index 42131b4..df76997 100644 --- a/lib/tools/find/recommend_page.dart +++ b/lib/tools/find/recommend_page.dart @@ -47,7 +47,7 @@ class _RecommendPageState extends State with AutomaticKeepAliveCl case "tuijian": //推荐 recommendList = (value['data'] as List).map((e) => RecommendBean.fromJson(e as Map)).toList(); break; - case "xiaoshuo": //推荐 + case "xiaoshuo": //小说 popularList = (value['data'] as List).map((e) => RecommendBean.fromJson(e as Map)).toList(); break; } @@ -200,7 +200,7 @@ class _RecommendPageState extends State with AutomaticKeepAliveCl child: CachedNetworkImage( width: 113, height: 159, - fit: BoxFit.fill, + fit: BoxFit.cover, imageUrl: res.imageUrl!, errorWidget: (context, url, error) => const Icon(Icons.error), ), @@ -256,7 +256,7 @@ class _RecommendPageState extends State with AutomaticKeepAliveCl child: CachedNetworkImage( width: 83, height: 115, - fit: BoxFit.fill, + fit: BoxFit.cover, imageUrl: data.imageUrl!, errorWidget: (context, url, error) => const Icon(Icons.error), ), diff --git a/lib/tools/home/home_chat_page.dart b/lib/tools/home/home_chat_page.dart index af11cd7..8b660a5 100644 --- a/lib/tools/home/home_chat_page.dart +++ b/lib/tools/home/home_chat_page.dart @@ -192,7 +192,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie height: 311.67, decoration: BoxDecoration( gradient: LinearGradient( - colors: [Color(0x00000000),Color(0x00000000), Color(0xFF0C0909), Color(0xFF0C0909)], // 三色渐变数组 + colors: [Color(0x00000000), Color(0x00000000), Color(0x00000000), Color(0xFF0C0909), Color(0xFF0C0909)], // 三色渐变数组 begin: Alignment.topCenter, // 渐变开始位置 end: Alignment.bottomCenter, // 渐变结束位置 ), @@ -209,13 +209,13 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie child: Stack( alignment: Alignment.center, children: [ - Positioned( - top: 0, - left: 105, - child: Text( - "+1", - style: TextStyle(color: Color(0xFFF14476), fontSize: 10), - )), + // Positioned( + // top: 0, + // left: 105, + // child: Text( + // "+1", + // style: TextStyle(color: Color(0xFFF14476), fontSize: 10), + // )), Positioned( left: 0, child: Container( @@ -243,8 +243,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie }, child: Container( margin: EdgeInsets.only(left: 2), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), + child: ClipOval( child: CachedNetworkImage( width: 23, height: 23, @@ -357,11 +356,11 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie return _item(index); }), )), - Container( - alignment: Alignment.centerLeft, - margin: EdgeInsets.only(left: 16, bottom: 3), - child: Image(width: 63, height: 18, image: AssetImage('assets/images/ic_memory.png')), - ), + // Container( + // alignment: Alignment.centerLeft, + // margin: EdgeInsets.only(left: 16, bottom: 3), + // child: Image(width: 63, height: 18, image: AssetImage('assets/images/ic_memory.png')), + // ), ///输入 功能 Container( @@ -444,7 +443,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie margin: const EdgeInsets.only(left: 14, right: 14), child: GestureDetector( onTap: () { - Navigator.of(context).pushNamed('/LoginPage'); + // Navigator.of(context).pushNamed('/OverlayView'); }, child: Image( width: 27, @@ -465,7 +464,7 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie }, child: Image( width: 27, - image: AssetImage('assets/images/ic_more.png'), + image: !isMore ? AssetImage('assets/images/ic_more.png') : AssetImage('assets/images/ic_more_no.png'), ), ), ], @@ -524,6 +523,31 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ), ), ), + Container( + margin: EdgeInsets.only(left: 23), + child: GestureDetector( + onTap: () { + setState(() { + isMore = false; + }); + // EasyLoading.show(status: 'loading...'); + // _viewmodel.delChat(widget.characterId); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image(width: 26, height: 26, image: AssetImage('assets/images/ic_memory.png')), + Container( + margin: EdgeInsets.only(top: 9), + child: Text( + '记忆提升', + style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)), + ), + ), + ], + ), + ), + ), ], ), ) @@ -532,15 +556,6 @@ class _HomeChatPageState extends State with AutomaticKeepAliveClie ), ), - ///记忆提升中 - Positioned( - top: (MediaQuery.of(context).padding.top) * 2 + 10, - left: 16, - child: Image( - width: 47, - height: 12, - image: AssetImage('assets/images/ic_memory_p.png'), - )), ], ), ); diff --git a/lib/tools/home_page.dart b/lib/tools/home_page.dart index fa26d62..278e5e6 100644 --- a/lib/tools/home_page.dart +++ b/lib/tools/home_page.dart @@ -7,6 +7,7 @@ import 'package:talk/tools/home/my_home_page.dart'; import 'package:talk/tools/me/me_page.dart'; import 'package:talk/tools/message/message_page.dart'; +import '../network/NetworkConfig.dart'; import 'find/find_page.dart'; class HomePage extends StatefulWidget { @@ -193,6 +194,12 @@ class _HomePageState extends State with SingleTickerProviderStateMixin unselectedFontSize: 15, iconSize: 0, onTap: (index) { + + if (NetworkConfig.userId == "") { + Navigator.of(context).pushNamed('/LoginPage'); + return; + } + setState(() { currentIndex = index; }); diff --git a/lib/tools/me/me_model.dart b/lib/tools/me/me_model.dart new file mode 100644 index 0000000..33d39e3 --- /dev/null +++ b/lib/tools/me/me_model.dart @@ -0,0 +1,60 @@ +import 'dart:async'; + +import 'package:talk/network/NetworkConfig.dart'; +import 'package:talk/network/RequestCenter.dart'; + +import '../../beans/account_bean.dart'; +import '../../beans/user_info_bean.dart'; +import '../../network/BaseEntity.dart'; + +class MeModel { + StreamController streamController = StreamController.broadcast(); + + MeModel() { + setUp(); + } + + void setUp() {} + + ///用户信息 + Future getUserInfo() async { + RequestCenter.instance.requestGet(NetworkConfig.getUserInfo, {}, (BaseEntity dataEntity) { + if (dataEntity.code == 0) { + UserInfoBean userInfoBean = UserInfoBean.fromJson(dataEntity.data); + + streamController.sink.add({ + 'code': "getUserInfo", //有数据 + 'data': userInfoBean, + }); + } else { + streamController.sink.add({ + 'code': "error", // + 'data': dataEntity.message, + }); + } + }, (ErrorEntity errorEntity) { + print("errorEntity==${errorEntity.message}"); + }); + } + + ///账户信息 + Future getMyAccount() async { + RequestCenter.instance.requestGet(NetworkConfig.getMyAccount, {}, (BaseEntity dataEntity) { + if (dataEntity.code == 0) { + AccountBean accountBean = AccountBean.fromJson(dataEntity.data); + + streamController.sink.add({ + 'code': "getMyAccount", //有数据 + 'data': accountBean, + }); + } else { + streamController.sink.add({ + 'code': "error", // + 'data': dataEntity.message, + }); + } + }, (ErrorEntity errorEntity) { + print("errorEntity==${errorEntity.message}"); + }); + } +} diff --git a/lib/tools/me/me_page.dart b/lib/tools/me/me_page.dart index ef933e9..b86d361 100644 --- a/lib/tools/me/me_page.dart +++ b/lib/tools/me/me_page.dart @@ -1,4 +1,12 @@ +import 'dart:async'; + +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:talk/tools/me/me_model.dart'; + +import '../../beans/me_character_info_bean.dart'; +import '../../beans/user_info_bean.dart'; +import '../chat/chat_page.dart'; class MePage extends StatefulWidget { const MePage({super.key}); @@ -8,259 +16,319 @@ class MePage extends StatefulWidget { } class _MePageState extends State { + late StreamSubscription subscription; + final MeModel _viewmodel = MeModel(); + + late UserInfoBean userInfoBean; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + subscription = _viewmodel.streamController.stream.listen((newData) { + String code = newData['code']; + if (code.isNotEmpty) { + switch (code) { + case "getUserInfo": + userInfoBean = newData['data']; + break; + } + setState(() {}); + } + }); + _viewmodel.getUserInfo(); + } + + @override + void dispose() { + // TODO: implement dispose + subscription.cancel(); + super.dispose(); + } + + goChatPage(String id) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChatPage( + characterId: id, + )), + ); + } + @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFF121213), - body: Stack( - children: [ - Container( - margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 9), - child: Column( - children: [ - ///title - SizedBox( - width: double.infinity, - child: Stack( - alignment: Alignment.center, - children: [ - Text( - '', - style: TextStyle(color: Colors.white, fontSize: 18), - ), - - ///设置按钮 - Positioned( - right: 15, - child: GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/SettingPage'); - }, - child: Image( - width: 21, - height: 21, - image: AssetImage('assets/images/ic_setting.png'), - ), - )) - ], - ), - ), - - Container( - width: double.infinity, - margin: EdgeInsets.only(left: 18, right: 18, top: 38), - child: Stack( - children: [ - Image(width: 58, image: AssetImage('assets/images/img_head2.png')), - Positioned( - top: 5, - left: 80, - child: Text( - '王语嫣', - style: TextStyle(fontSize: 15, color: Color(0xFFE1E1E1)), - )), - Positioned( - bottom: 6, - left: 80, - child: Text( - 'id 13121331', - style: TextStyle(fontSize: 13, color: Color(0xFF4D4D4D)), - )), - ], - ), - ), - Container( - margin: EdgeInsets.only(left: 16, top: 17), - child: Row( - children: [ - Text( - '9', - style: TextStyle(color: Colors.white, fontSize: 16), - ), - Container( - margin: EdgeInsets.only(left: 6), - child: Text( - '相册', - style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), + body: SingleChildScrollView( + child: Stack( + children: [ + Container( + margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 9), + child: Column( + children: [ + ///title + SizedBox( + width: double.infinity, + child: Stack( + alignment: Alignment.center, + children: [ + Text( + '', + style: TextStyle(color: Colors.white, fontSize: 18), ), - ), - Container( - margin: EdgeInsets.only(left: 22), - child: Text( + ///设置按钮 + Positioned( + right: 15, + child: GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/SettingPage'); + }, + child: Image( + width: 21, + height: 21, + image: AssetImage('assets/images/ic_setting.png'), + ), + )) + ], + ), + ), + + Container( + width: double.infinity, + margin: EdgeInsets.only(left: 18, right: 18, top: 38), + child: Stack( + children: [ + ClipOval( + child: CachedNetworkImage( + width: 58, + height: 58, + imageUrl: userInfoBean.userIconUrl!, + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), + Positioned( + top: 5, + left: 80, + child: Text( + '${userInfoBean.nickName}', + style: TextStyle(fontSize: 15, color: Color(0xFFE1E1E1)), + )), + Positioned( + bottom: 6, + left: 80, + child: Text( + 'id ${userInfoBean.userId}', + style: TextStyle(fontSize: 13, color: Color(0xFF4D4D4D)), + )), + ], + ), + ), + Container( + margin: EdgeInsets.only(left: 16, top: 17), + child: Row( + children: [ + Text( '9', style: TextStyle(color: Colors.white, fontSize: 16), ), - ), - Container( - margin: EdgeInsets.only(left: 6), - child: Text( - '聊过', - style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), - ), - ), - ], - ), - ), - - ///货币 商城 - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 22), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/AccountPage'); - }, - child: Container( - width: 151, - height: 38, - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 15), - child: Image( - width: 23, - height: 20, - image: AssetImage('assets/images/ic_currency.png'), - ), - ), - Container( - margin: EdgeInsets.only(left: 17), - child: Text( - '货币:23233', - style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), - ), - ), - ], + Container( + margin: EdgeInsets.only(left: 6), + child: Text( + '相册', + style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), ), ), - ), - GestureDetector( - onTap: () { - Navigator.pushNamed(context, '/ShopPage'); - }, - child: Container( - width: 151, - height: 38, - margin: EdgeInsets.only(left: 26), - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Row( - children: [ - Container( - margin: EdgeInsets.only(left: 15), - child: Image( - width: 23, - height: 20, - image: AssetImage('assets/images/ic_mall.png'), - ), - ), - Container( - margin: EdgeInsets.only(left: 24), - child: Text( - '货币商城', - style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), - ), - ), - ], + Container( + margin: EdgeInsets.only(left: 22), + child: Text( + '9', + style: TextStyle(color: Colors.white, fontSize: 16), ), ), - ), - ], - ), - ), - - Container( - height: 50, - margin: EdgeInsets.symmetric(horizontal: 16), - child: Image( - image: AssetImage('assets/images/ic_web.png'), - ), - ), - - Container( - margin: EdgeInsets.only(left: 16, top: 33), - child: Row( - children: [ - Text( - '创作中心', - style: TextStyle(color: Color(0xFFE1E1E1)), - ), - Container( - margin: EdgeInsets.only(left: 9), - child: Text( - '0', - style: TextStyle(color: Color(0xFF4D4D4D)), + Container( + margin: EdgeInsets.only(left: 6), + child: Text( + '聊过', + style: TextStyle(color: Color(0xFF4D4D4D), fontSize: 12), + ), ), - ), - ], + ], + ), ), - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 17), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: 150, - height: 58, - padding: EdgeInsets.only(left: 20), - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Text( - '创建个人模型', - style: TextStyle(fontSize: 12, color: Color(0xFFE1E1E1)), - ), + ///货币 商城 + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 22), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/AccountPage'); + }, + child: Container( + width: 151, + height: 38, + decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 15), + child: Image( + width: 23, + height: 20, + image: AssetImage('assets/images/ic_currency.png'), + ), + ), + Container( + margin: EdgeInsets.only(left: 17), + child: Text( + '货币:${userInfoBean.currency}', + style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + ), + ), + ], ), - Container( - margin: EdgeInsets.only(top: 7), - child: Text( - '本周剩余(5/5)', - style: TextStyle(fontSize: 10, color: Color(0xFF4D4D4D)), - ), - ), - ], + ), ), - ), - Container( - width: 150, - height: 58, - padding: EdgeInsets.only(left: 20), - decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Text( - '创建个人模型', - style: TextStyle(fontSize: 12, color: Color(0xFFE1E1E1)), - ), + GestureDetector( + onTap: () { + Navigator.pushNamed(context, '/ShopPage'); + }, + child: Container( + width: 151, + height: 38, + margin: EdgeInsets.only(left: 26), + decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(13))), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(left: 15), + child: Image( + width: 23, + height: 20, + image: AssetImage('assets/images/ic_mall.png'), + ), + ), + Container( + margin: EdgeInsets.only(left: 24), + child: Text( + '货币商城', + style: TextStyle(color: Color(0xFFE1E1E1), fontSize: 13), + ), + ), + ], ), - Container( - margin: EdgeInsets.only(top: 7), - child: Text( - '本周剩余(5/5)', - style: TextStyle(fontSize: 10, color: Color(0xFF4D4D4D)), - ), - ), - ], + ), ), - ), - ], + ], + ), ), - ), - ], - ), - ) - ], + + Container( + height: 50, + margin: EdgeInsets.symmetric(horizontal: 16), + child: Image( + image: AssetImage('assets/images/ic_web.png'), + ), + ), + + Container( + margin: EdgeInsets.only(left: 16, top: 33), + child: Row( + children: [ + Text( + '创作中心', + style: TextStyle(color: Color(0xFFE1E1E1)), + ), + Container( + margin: EdgeInsets.only(left: 9), + child: Text( + '0', + style: TextStyle(color: Color(0xFF4D4D4D)), + ), + ), + ], + ), + ), + + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 17), + child: GridView.count( + shrinkWrap: true, + //水平子Widget之间间距 + crossAxisSpacing: 12.0, + //垂直子Widget之间间距 + mainAxisSpacing: 9.0, + //GridView内边距 + padding: EdgeInsets.zero, + //一行的Widget数量 + crossAxisCount: 3, + //子Widget宽高比例 + childAspectRatio: 0.7, + //子Widget列表 + children: _item(userInfoBean.characterInfo!), + physics: NeverScrollableScrollPhysics(), + //类似 cellForRow 函数 + scrollDirection: Axis.vertical), + ), + ], + ), + ) + ], + ), ), ); } + + _item(List list) { + return list.map((res) { + int index = list.indexOf(res); + return GestureDetector( + onTap: () { + goChatPage(res.characterId.toString()); + }, + child: Container( + alignment: Alignment.center, + // margin: EdgeInsets.only(right: 9, left: 16), + child: Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(15)), + child: CachedNetworkImage( + width: 113, + height: 159, + fit: BoxFit.cover, + imageUrl: res.bgImage!, + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), + Positioned( + left: 7, + bottom: 5, + child: Text( + '${res.characterName}', + style: TextStyle(color: Colors.white, fontSize: 12), + )), + // Positioned( + // left: 7, + // bottom: 9, + // child: Container( + // width: 105, + // child: Text( + // '${res.biography}', + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // style: TextStyle(color: Color(0xFFC2C2C2), fontSize: 9), + // ), + // )), + ], + ), + ), + ); + }).toList(); + } + } diff --git a/lib/tools/message/message_page.dart b/lib/tools/message/message_page.dart index 73f5375..3828f33 100644 --- a/lib/tools/message/message_page.dart +++ b/lib/tools/message/message_page.dart @@ -135,13 +135,16 @@ class _MessagePageState extends State { child: Stack( alignment: Alignment.center, children: [ + ///头像 Positioned( left: 16, - child: CachedNetworkImage( - width: 40, - height: 40, - imageUrl: data.iconImage!, - errorWidget: (context, url, error) => const Icon(Icons.error), + child: ClipOval( + child: CachedNetworkImage( + width: 40, + height: 40, + imageUrl: data.iconImage!, + errorWidget: (context, url, error) => const Icon(Icons.error), + ), ), ), Positioned( diff --git a/lib/tools/shop/account_page.dart b/lib/tools/shop/account_page.dart index afba2f5..3be9f4f 100644 --- a/lib/tools/shop/account_page.dart +++ b/lib/tools/shop/account_page.dart @@ -1,5 +1,11 @@ -import 'package:flutter/material.dart'; +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:talk/tools/shop/shop_model.dart'; +import 'package:talk/tools/shop/transaction_page.dart'; + +import '../../beans/account_bean.dart'; +import '../../beans/transaction_records_bean.dart'; ///货币 class AccountPage extends StatefulWidget { @@ -11,6 +17,40 @@ class AccountPage extends StatefulWidget { class _AccountPageState extends State { List dataList = [1, 2, 3, 4, 5, 6]; + late StreamSubscription subscription; + final ShopModel _viewmodel = ShopModel(); + late AccountBean accountBean; + List recordList = []; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + subscription = _viewmodel.streamController.stream.listen((newData) { + String code = newData['code']; + if (code.isNotEmpty) { + switch (code) { + case "getMyAccount": + accountBean = newData['data']; + break; + case "getTransactionRecords": + recordList = newData['data']; + break; + } + setState(() {}); + } + }); + _viewmodel.getMyAccount(); + _viewmodel.getTransactionRecords(); + } + + @override + void dispose() { + // TODO: implement dispose + subscription.cancel(); + super.dispose(); + } @override Widget build(BuildContext context) { @@ -44,7 +84,7 @@ class _AccountPageState extends State { alignment: Alignment.center, margin: EdgeInsets.only(top: 40), child: Text( - '0', + '${accountBean.currency}', style: TextStyle(fontSize: 24, color: Color(0xFFE1E1E1)), ), ), @@ -92,7 +132,13 @@ class _AccountPageState extends State { GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { - Navigator.pushNamed(context, '/TransactionPage'); + // Navigator.pushNamed(context, '/TransactionPage'); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TransactionPage( + recordList: recordList, + ))); }, child: const SizedBox( height: 35, @@ -166,7 +212,7 @@ class _AccountPageState extends State { } _item() { - return dataList.map((res) { + return accountBean.currencyRechargeList!.map((res) { return Container( height: 58, decoration: BoxDecoration(color: Color(0xFF2A2A2A), borderRadius: BorderRadius.all(Radius.circular(17))), @@ -176,21 +222,21 @@ class _AccountPageState extends State { left: 21, top: 14, child: Text( - '100', + '${res.currencyCount}', style: TextStyle(color: Color(0xFFFF9000), fontSize: 13), )), Positioned( left: 48, top: 16, child: Text( - '货币', + '语珠', style: TextStyle(color: Color(0xFF6F6F6F), fontSize: 10), )), Positioned( left: 21, top: 34, child: Text( - '1元', + '${res.price}元', style: TextStyle(color: Colors.white, fontSize: 10), )), ], diff --git a/lib/tools/shop/shop_model.dart b/lib/tools/shop/shop_model.dart new file mode 100644 index 0000000..bd1903e --- /dev/null +++ b/lib/tools/shop/shop_model.dart @@ -0,0 +1,83 @@ +import 'dart:async'; + +import 'package:talk/network/NetworkConfig.dart'; +import 'package:talk/network/RequestCenter.dart'; + +import '../../beans/account_bean.dart'; +import '../../beans/mall_bean.dart'; +import '../../beans/transaction_records_bean.dart'; +import '../../network/BaseEntity.dart'; + +class ShopModel { + StreamController streamController = StreamController.broadcast(); + + ShopModel() { + setUp(); + } + + void setUp() {} + + ///账户信息 + Future getMyAccount() async { + RequestCenter.instance.requestGet(NetworkConfig.getMyAccount, {}, (BaseEntity dataEntity) { + if (dataEntity.code == 0) { + AccountBean accountBean = AccountBean.fromJson(dataEntity.data); + + streamController.sink.add({ + 'code': "getMyAccount", //有数据 + 'data': accountBean, + }); + } else { + streamController.sink.add({ + 'code': "error", // + 'data': dataEntity.message, + }); + } + }, (ErrorEntity errorEntity) { + print("errorEntity==${errorEntity.message}"); + }); + } + + ///交易记录 + Future getTransactionRecords() async { + RequestCenter.instance.requestGet(NetworkConfig.getTransactionRecords, {}, (BaseEntity dataEntity) { + if (dataEntity.code == 0) { + List data = + (dataEntity.data as List).map((e) => TransactionRecordsBean.fromJson(e as Map)).toList(); + + streamController.sink.add({ + 'code': "getTransactionRecords", //有数据 + 'data': data, + }); + } else { + streamController.sink.add({ + 'code': "error", // + 'data': dataEntity.message, + }); + } + }, (ErrorEntity errorEntity) { + print("errorEntity==${errorEntity.message}"); + }); + } + + ///交易记录 + Future getMallItem() async { + RequestCenter.instance.requestGet(NetworkConfig.getMallItem, {}, (BaseEntity dataEntity) { + if (dataEntity.code == 0) { + MallBean mallBean = MallBean.fromJson(dataEntity.data); + + streamController.sink.add({ + 'code': "getMallItem", //有数据 + 'data': mallBean, + }); + } else { + streamController.sink.add({ + 'code': "error", // + 'data': dataEntity.message, + }); + } + }, (ErrorEntity errorEntity) { + print("errorEntity==${errorEntity.message}"); + }); + } +} diff --git a/lib/tools/shop/shop_page.dart b/lib/tools/shop/shop_page.dart index 70af81c..8bb0344 100644 --- a/lib/tools/shop/shop_page.dart +++ b/lib/tools/shop/shop_page.dart @@ -1,4 +1,11 @@ +import 'dart:async'; + +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:talk/tools/shop/shop_model.dart'; + +import '../../beans/mall_bean.dart'; +import '../../beans/mall_item_bean.dart'; ///货币商城 class ShopPage extends StatefulWidget { @@ -12,10 +19,35 @@ class _ShopPageState extends State { int currentIndex = 0; List dataList = [1, 2, 3, 4, 5]; + late StreamSubscription subscription; + final ShopModel _viewmodel = ShopModel(); + + late MallBean mallBean; + @override void initState() { // TODO: implement initState super.initState(); + + subscription = _viewmodel.streamController.stream.listen((newData) { + String code = newData['code']; + if (code.isNotEmpty) { + switch (code) { + case "getMallItem": + mallBean = newData['data']; + break; + } + setState(() {}); + } + }); + _viewmodel.getMallItem(); + } + + @override + void dispose() { + // TODO: implement dispose + subscription.cancel(); + super.dispose(); } @override @@ -116,7 +148,7 @@ class _ShopPageState extends State { //子Widget宽高比例 childAspectRatio: 1.0, //子Widget列表 - children: _item(), + children: _item(currentIndex == 0 ? mallBean.mall! : mallBean.purchased!), physics: NeverScrollableScrollPhysics(), //类似 cellForRow 函数 scrollDirection: Axis.vertical), @@ -128,32 +160,18 @@ class _ShopPageState extends State { ); } - _item() { - return dataList.map((res) { + _item(List list) { + return list.map((res) { return Column( children: [ - Container( - width: double.infinity, - height: 100, - decoration: BoxDecoration( - color: Color(0xFF2A2A2A), - borderRadius: BorderRadius.all(Radius.circular(7)), - ), - ), - Container( - alignment: Alignment.centerLeft, - margin: EdgeInsets.only(top: 7), - child: Text( - '气泡气泡', - style: TextStyle(color: Colors.white, fontSize: 11), - ), - ), - Container( - alignment: Alignment.centerLeft, - margin: EdgeInsets.only(top: 7), - child: Text( - '100 货币', - style: TextStyle(color: Color(0xFFFF9000), fontSize: 11), + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(15)), + child: CachedNetworkImage( + width: 155, + height: 100, + fit: BoxFit.cover, + imageUrl: res.imgUrl!, + errorWidget: (context, url, error) => const Icon(Icons.error), ), ), ], diff --git a/lib/tools/shop/transaction_page.dart b/lib/tools/shop/transaction_page.dart index 9eeee1d..93c6e0d 100644 --- a/lib/tools/shop/transaction_page.dart +++ b/lib/tools/shop/transaction_page.dart @@ -1,7 +1,11 @@ import 'package:flutter/material.dart'; +import '../../beans/transaction_records_bean.dart'; + class TransactionPage extends StatefulWidget { - const TransactionPage({super.key}); + List recordList; + + TransactionPage({required this.recordList}); @override State createState() => _TransactionPageState(); @@ -35,9 +39,9 @@ class _TransactionPageState extends State { child: Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 20), child: ListView.builder( - itemCount: 5, + itemCount: widget.recordList.length, itemBuilder: (BuildContext context, int index) { - return _item(index); + return _item(index,widget.recordList[index]); }), ), ), @@ -46,7 +50,7 @@ class _TransactionPageState extends State { ); } - _item(index) { + _item(index,TransactionRecordsBean data) { return Container( width: double.infinity, height: 70, @@ -66,20 +70,20 @@ class _TransactionPageState extends State { top: 15, left: 0, child: Text( - '100货币', + '${data.transactionContent}', style: TextStyle(fontSize: 11, color: Colors.white), )), Positioned( bottom: 14, left: 0, child: Text( - '2024-7-3 10:00', + '${data.transactionTime}', style: TextStyle(fontSize: 10, color: Color(0xFF6F6F6F)), )), Positioned( right: 0, child: Text( - '-100元', + '${data.transactionAmount}元', style: TextStyle(fontSize: 11, color: Colors.white), )), ],