merge
This commit is contained in:
parent
a000a4aeea
commit
27001b12d6
@ -14,7 +14,12 @@ import 'package:loopin/utils/scan_code_type.dart';
|
||||
import 'package:pretty_qr_code/pretty_qr_code.dart';
|
||||
|
||||
class MyQrcode extends StatelessWidget {
|
||||
MyQrcode({super.key});
|
||||
MyQrcode({
|
||||
super.key,
|
||||
this.prefix,
|
||||
});
|
||||
|
||||
final String? prefix;
|
||||
|
||||
final controller = Get.find<ImUserInfoController>();
|
||||
|
||||
@ -22,12 +27,14 @@ class MyQrcode extends StatelessWidget {
|
||||
final GlobalKey _qrKey = GlobalKey();
|
||||
|
||||
/// 将 Widget 渲染为 Uint8List
|
||||
Future<Uint8List?> capturePng() async {
|
||||
Future<Uint8List?> capturePng(BuildContext context) async {
|
||||
try {
|
||||
final boundary = _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
|
||||
if (boundary == null) return null;
|
||||
|
||||
final image = await boundary.toImage(pixelRatio: ui.window.devicePixelRatio);
|
||||
// final image = await boundary.toImage(pixelRatio: ui.window.devicePixelRatio);
|
||||
final pixelRatio = View.of(context).devicePixelRatio;
|
||||
final image = await boundary.toImage(pixelRatio: pixelRatio);
|
||||
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||
return byteData?.buffer.asUint8List();
|
||||
} catch (e) {
|
||||
@ -39,7 +46,7 @@ class MyQrcode extends StatelessWidget {
|
||||
/// 保存二维码到相册
|
||||
Future<void> saveQrToGallery() async {
|
||||
logger.w('长安了');
|
||||
final pngBytes = await capturePng();
|
||||
final pngBytes = await capturePng(Get.context!);
|
||||
if (pngBytes == null) return;
|
||||
|
||||
final result = await ImageGallerySaverPlus.saveImage(
|
||||
@ -67,6 +74,8 @@ class MyQrcode extends StatelessWidget {
|
||||
face = CachedNetworkImageProvider(faceUrl);
|
||||
}
|
||||
|
||||
final data = '${prefix ?? QrTypeCode.hym}$userID';
|
||||
|
||||
return GestureDetector(
|
||||
onLongPress: () {
|
||||
showModalBottomSheet(
|
||||
@ -104,7 +113,7 @@ class MyQrcode extends StatelessWidget {
|
||||
key: _qrKey,
|
||||
child: PrettyQrView.data(
|
||||
errorCorrectLevel: QrErrorCorrectLevel.H, // 高容错
|
||||
data: '${QrTypeCode.hym}$userID',
|
||||
data: data, // 二维码内容
|
||||
decoration: PrettyQrDecoration(
|
||||
background: Colors.transparent,
|
||||
shape: const PrettyQrShape.custom(
|
||||
|
@ -1713,26 +1713,54 @@ class _ChatNoFriendState extends State<ChatNoFriend> with SingleTickerProviderSt
|
||||
),
|
||||
onPressed: () async {
|
||||
// 回关
|
||||
final res = await ImService.instance.followUser(userIDList: [arguments.value.userID!]);
|
||||
if (res.success) {
|
||||
final ctl = Get.find<ChatController>();
|
||||
|
||||
final chatRes = await ImService.instance.followUser(userIDList: [arguments.value.userID!]);
|
||||
if (chatRes.success) {
|
||||
controller.isFriend.value = true;
|
||||
controller.followType.value = 3;
|
||||
if (arguments.value.conversationGroupList?.isNotEmpty == true) {
|
||||
//把会话数据从陌生人分组移除
|
||||
final ctl = Get.find<ChatController>();
|
||||
ctl.removeNoFriend(conversationID: arguments.value.conversationID);
|
||||
ctl.updateNoFriendMenu();
|
||||
final res = await ImService.instance.getConversation(conversationID: 'c2c_${arguments.value.userID}');
|
||||
if (res.success) {
|
||||
V2TimConversation conversation = res.data;
|
||||
if (conversation.conversationGroupList?.isNotEmpty ?? false) {
|
||||
await ImService.instance.deleteConversationsFromGroup(
|
||||
groupName: conversation.conversationGroupList!.first!,
|
||||
conversationIDList: [conversation.conversationID],
|
||||
);
|
||||
await ctl.updateNoFriendMenu();
|
||||
// 跳转到chat地址,销毁当前页面
|
||||
Get.offAllNamed(
|
||||
'/chat',
|
||||
arguments: arguments.value,
|
||||
predicate: (route) {
|
||||
// 清理栈,只保留 `/`
|
||||
return route.settings.name == '/';
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
// 跳转到chat地址,销毁当前页面
|
||||
Get.offAllNamed(
|
||||
'/chat',
|
||||
arguments: arguments.value,
|
||||
predicate: (route) {
|
||||
// 清理栈,只保留 `/`
|
||||
return route.settings.name == '/';
|
||||
},
|
||||
);
|
||||
}
|
||||
// 回关
|
||||
// final res = await ImService.instance.followUser(userIDList: [arguments.value.userID!]);
|
||||
// if (res.success) {
|
||||
// controller.isFriend.value = true;
|
||||
// controller.followType.value = 3;
|
||||
// if (arguments.value.conversationGroupList?.isNotEmpty == true) {
|
||||
// //把会话数据从陌生人分组移除
|
||||
// final ctl = Get.find<ChatController>();
|
||||
// await ctl.removeNoFriend(conversationID: arguments.value.conversationID);
|
||||
// ctl.updateNoFriendMenu();
|
||||
// // 跳转到chat地址,销毁当前页面
|
||||
// Get.offAllNamed(
|
||||
// '/chat',
|
||||
// arguments: arguments.value,
|
||||
// predicate: (route) {
|
||||
// // 清理栈,只保留 `/`
|
||||
// return route.settings.name == '/';
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
},
|
||||
child: const Text('回关', style: TextStyle(color: Colors.white)),
|
||||
),
|
||||
|
@ -107,11 +107,15 @@ class _AddFriendState extends State<AddFriend> {
|
||||
suffixIcon: TextButton(
|
||||
child: Text('搜索'),
|
||||
onPressed: () {
|
||||
// 点击按钮时触发的逻辑
|
||||
// 点击按钮搜索
|
||||
final value = txtcontroller.text.trim();
|
||||
if (value.isNotEmpty) {
|
||||
// 跳转搜索页
|
||||
focusNode.unfocus();
|
||||
Get.toNamed(
|
||||
'/search-result',
|
||||
arguments: {'searchWords': value, 'tab': 2},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -124,8 +128,12 @@ class _AddFriendState extends State<AddFriend> {
|
||||
),
|
||||
onSubmitted: (value) {
|
||||
if (value.trim().isNotEmpty) {
|
||||
focusNode.unfocus();
|
||||
// 跳转搜索页
|
||||
focusNode.unfocus();
|
||||
Get.toNamed(
|
||||
'/search-result',
|
||||
arguments: {'searchWords': value, 'tab': 2},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -155,6 +163,7 @@ class _AddFriendState extends State<AddFriend> {
|
||||
|
||||
SizedBox(height: 20),
|
||||
|
||||
// 我的二维码
|
||||
MyQrcode(),
|
||||
],
|
||||
),
|
||||
|
@ -42,7 +42,6 @@ class _GoodsState extends State<Goods> {
|
||||
double scrollOffset = 0;
|
||||
// 分享列表
|
||||
List shareList = [
|
||||
{'icon': 'assets/images/share-wx.png', 'label': '好友'},
|
||||
{'icon': 'assets/images/share-wx.png', 'label': '微信'},
|
||||
{'icon': 'assets/images/share-pyq.png', 'label': '朋友圈'},
|
||||
];
|
||||
@ -105,11 +104,12 @@ class _GoodsState extends State<Goods> {
|
||||
}
|
||||
|
||||
void handleShareClick(int index) {
|
||||
final description = shopObj['describe']; // 商品描述
|
||||
if (index == 1) {
|
||||
logger.w(shopObj);
|
||||
final description = shopObj['describe'] ?? '未上传商品描述'; // 商品描述
|
||||
if (index == 0) {
|
||||
// 好友
|
||||
Wxsdk.shareToFriend(title: '快看看我分享的商品', description: description, webpageUrl: '${ShareType.shop.name}?id=${shopObj['id']}');
|
||||
} else if (index == 2) {
|
||||
} else if (index == 1) {
|
||||
// 朋友圈
|
||||
Wxsdk.shareToTimeline(title: '快看看我分享的商品', webpageUrl: '${ShareType.shop.name}?id=${shopObj['id']}');
|
||||
}
|
||||
@ -178,7 +178,9 @@ class _GoodsState extends State<Goods> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 20.0),
|
||||
itemBuilder: (context, index) {
|
||||
return GestureDetector(
|
||||
onTap: () => handleShareClick(index),
|
||||
onTap: () {
|
||||
handleShareClick(index);
|
||||
},
|
||||
child: Container(
|
||||
width: 64,
|
||||
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
|
@ -1,6 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/IM/controller/im_user_info_controller.dart';
|
||||
import 'package:loopin/components/my_qrcode.dart';
|
||||
import 'package:loopin/pages/my/merchant/balance/balance.dart';
|
||||
import 'package:loopin/pages/my/merchant/balance/controller.dart';
|
||||
import 'package:loopin/utils/scan_code_type.dart';
|
||||
|
||||
class AllFunctionsPage extends StatefulWidget {
|
||||
const AllFunctionsPage({super.key});
|
||||
@ -29,6 +33,7 @@ class _AllFunctionsPageState extends State<AllFunctionsPage> {
|
||||
]
|
||||
},
|
||||
];
|
||||
final ImUserInfoController controller = Get.find<ImUserInfoController>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -106,7 +111,12 @@ class _AllFunctionsPageState extends State<AllFunctionsPage> {
|
||||
itemCount: (section['items'] as List).length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = (section['items'] as List)[index];
|
||||
return _buildFunctionItem(item);
|
||||
final role = controller.role.value;
|
||||
if (item['id'] == 'home_promo' && role != 4) {
|
||||
return SizedBox();
|
||||
} else {
|
||||
return _buildFunctionItem(item);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@ -137,7 +147,7 @@ class _AllFunctionsPageState extends State<AllFunctionsPage> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
SizedBox(
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: Center(
|
||||
@ -176,18 +186,25 @@ class _AllFunctionsPageState extends State<AllFunctionsPage> {
|
||||
Get.toNamed('/myOrder');
|
||||
break;
|
||||
case 'home_balance':
|
||||
showLogoutDialog(context);
|
||||
// 钱包
|
||||
Get.put(BalanceController());
|
||||
Get.to(() => Balance());
|
||||
// showLogoutDialog(context);
|
||||
break;
|
||||
case 'home_withdraw':
|
||||
Get.toNamed('/vloger');
|
||||
break;
|
||||
case 'home_promo':
|
||||
// 推广码
|
||||
Get.to(() => MyQrcode(
|
||||
prefix: QrTypeCode.tgm,
|
||||
));
|
||||
break;
|
||||
case 'more_seller_order':
|
||||
Get.toNamed('/sellerOrder');
|
||||
case 'more_seller_order':
|
||||
Get.toNamed('/sellerOrder');
|
||||
break;
|
||||
case 'more_seller_income':
|
||||
Get.toNamed('/merchant/income');
|
||||
Get.toNamed('/merchant/income');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -211,7 +228,7 @@ class _AllFunctionsPageState extends State<AllFunctionsPage> {
|
||||
},
|
||||
child: const Text('取消', style: TextStyle(color: Colors.black54)),
|
||||
),
|
||||
TextButton(onPressed: ()=>{}, child: const Text('退出登录', style: TextStyle(color: Colors.red))),
|
||||
TextButton(onPressed: () => {}, child: const Text('退出登录', style: TextStyle(color: Colors.red))),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
@ -5,15 +5,18 @@ import 'package:get/get.dart';
|
||||
import 'package:get/get_rx/src/rx_typedefs/rx_typedefs.dart';
|
||||
import 'package:loopin/IM/controller/im_user_info_controller.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:loopin/api/video_api.dart';
|
||||
import 'package:loopin/api/common_api.dart';
|
||||
import 'package:loopin/utils/index.dart';
|
||||
import 'package:loopin/api/video_api.dart';
|
||||
import 'package:loopin/components/custom_sticky_header.dart';
|
||||
import 'package:loopin/components/my_confirm.dart';
|
||||
import 'package:loopin/components/my_qrcode.dart';
|
||||
import 'package:loopin/components/network_or_asset_image.dart';
|
||||
import 'package:loopin/components/only_down_scroll_physics.dart';
|
||||
import 'package:loopin/controller/video_module_controller.dart';
|
||||
import 'package:loopin/service/http.dart';
|
||||
import 'package:loopin/styles/index.dart';
|
||||
import 'package:loopin/utils/index.dart';
|
||||
import 'package:loopin/utils/scan_code_type.dart';
|
||||
import 'package:nested_scroll_view_plus/nested_scroll_view_plus.dart';
|
||||
import 'package:shirne_dialog/shirne_dialog.dart';
|
||||
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_info.dart';
|
||||
@ -131,17 +134,14 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 获取用户的所有视频的点赞数量
|
||||
// 获取用户的所有视频的点赞数量
|
||||
void getUserLikesCount() async {
|
||||
try {
|
||||
final resData = await Http.get(CommonApi.accountInfo);
|
||||
if(resData != null && resData['code'] == 200){
|
||||
vlogLikeCount = resData['data']['vlogLikeCount']??0;
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
if (resData != null && resData['code'] == 200) {
|
||||
vlogLikeCount = resData['data']['vlogLikeCount'] ?? 0;
|
||||
}
|
||||
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// 添加控制子列表滚动的方法
|
||||
@ -263,121 +263,20 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
}
|
||||
}
|
||||
|
||||
// 删除当前用户发布的视频
|
||||
// 删除当前用户发布的视频
|
||||
void deletePersonalVideo(videoId) async {
|
||||
logger.i('删除视频${videoId}');
|
||||
logger.i('删除视频$videoId');
|
||||
try {
|
||||
final res = await Http.post('${VideoApi.deleteVideo}?id=${videoId}', data: {});
|
||||
logger.i('删除成功响应${res}');
|
||||
if(res != null && res['code'] == 200){
|
||||
final res = await Http.post('${VideoApi.deleteVideo}?id=$videoId', data: {});
|
||||
logger.i('删除成功响应$res');
|
||||
if (res != null && res['code'] == 200) {
|
||||
MyDialog.toast('删除成功', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.green.withAlpha(200)));
|
||||
loadData(0);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e('删除视频失败: $e');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// 显示删除确认对话框
|
||||
void showDeleteConfirmDialog(String videoId) {
|
||||
Get.dialog(
|
||||
Dialog(
|
||||
backgroundColor: Colors.white,
|
||||
surfaceTintColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// 图标
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red.withOpacity(0.1),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.delete_outline,
|
||||
color: Colors.red,
|
||||
size: 30,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
|
||||
// 标题
|
||||
Text(
|
||||
'删除视频',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
|
||||
// 描述
|
||||
Text(
|
||||
'确认要删除这个视频吗?\n删除后将无法恢复',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
|
||||
// 按钮区域
|
||||
Row(
|
||||
children: [
|
||||
// 取消按钮
|
||||
Expanded(
|
||||
child: OutlinedButton(
|
||||
onPressed: () => Get.back(),
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.grey[700],
|
||||
side: BorderSide(color: Colors.grey[300]!),
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Text('取消'),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
|
||||
// 确认按钮
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
deletePersonalVideo(videoId);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Text('确认删除'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: true,
|
||||
);
|
||||
}
|
||||
// 二维码名片弹窗
|
||||
void qrcodeAlertDialog(BuildContext context) {
|
||||
showDialog(
|
||||
@ -397,13 +296,14 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset('assets/images/pic1.jpg', width: 250.0, fit: BoxFit.contain),
|
||||
const SizedBox(height: 15.0),
|
||||
const Text('扫一扫,加好友',
|
||||
style: TextStyle(
|
||||
color: Colors.white38,
|
||||
fontSize: 14.0,
|
||||
)),
|
||||
MyQrcode(prefix: QrTypeCode.tgm)
|
||||
// Image.asset('assets/images/pic1.jpg', width: 250.0, fit: BoxFit.contain),
|
||||
// const SizedBox(height: 15.0),
|
||||
// const Text('扫一扫,加好友',
|
||||
// style: TextStyle(
|
||||
// color: Colors.white38,
|
||||
// fontSize: 14.0,
|
||||
// )),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -657,7 +557,7 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: _buildVdCard(listToShow[index],tabIndex),
|
||||
child: _buildVdCard(listToShow[index], tabIndex),
|
||||
);
|
||||
},
|
||||
childCount: listToShow.length,
|
||||
@ -683,48 +583,55 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildVdCard(item,tabIndex) {
|
||||
Widget _buildVdCard(item, tabIndex) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
//去视频详情
|
||||
Get.toNamed('/videoDetail', arguments: {'videoId': item['id']});
|
||||
},
|
||||
onLongPress: () {
|
||||
if(tabIndex == 0){ // 个人发布作品可以长按删除
|
||||
if (tabIndex == 0) {
|
||||
// 个人发布作品可以长按删除
|
||||
showModalBottomSheet(
|
||||
context: Get.context!,
|
||||
backgroundColor: Colors.white,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ListTile(
|
||||
// leading: const Icon(Icons.lock, color: Colors.black),
|
||||
// title: const Text('设为私密', style: TextStyle(color: Colors.black)),
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// // TODO: 修改为私密逻辑
|
||||
// },
|
||||
// ),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete, color: Colors.redAccent),
|
||||
title: const Text('删除视频', style: TextStyle(color: Colors.redAccent)),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
showDeleteConfirmDialog(item['id']);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
context: Get.context!,
|
||||
backgroundColor: Colors.white,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
builder: (context) {
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ListTile(
|
||||
// leading: const Icon(Icons.lock, color: Colors.black),
|
||||
// title: const Text('设为私密', style: TextStyle(color: Colors.black)),
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// // TODO: 修改为私密逻辑
|
||||
// },
|
||||
// ),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete, color: Colors.redAccent),
|
||||
title: const Text('删除视频', style: TextStyle(color: Colors.redAccent)),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
final confirmed = await ConfirmDialog.show(
|
||||
title: "提示",
|
||||
content: "确认要删除吗?",
|
||||
);
|
||||
if (confirmed == true) {
|
||||
Get.back();
|
||||
deletePersonalVideo(item['id']);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -830,35 +737,72 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
Row(
|
||||
children: [
|
||||
// 昵称 Obx
|
||||
Obx(() {
|
||||
final nickname = imUserInfoController?.nickname.value ?? '';
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(76),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
nickname.isNotEmpty ? nickname : '昵称',
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
Obx(
|
||||
() {
|
||||
final nickname = imUserInfoController?.nickname.value ?? '';
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(76),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(width: 8),
|
||||
InkWell(
|
||||
onTap: () => qrcodeAlertDialog(context),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(76),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: const Icon(Icons.qr_code_outlined, size: 18, color: Colors.white),
|
||||
),
|
||||
child: Text(
|
||||
nickname.isNotEmpty ? nickname : '昵称',
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
// 团长的二维码
|
||||
Obx(
|
||||
() {
|
||||
// MERCHANT(2, "商家"),
|
||||
// AGENT(3, "代理"),
|
||||
// PLATFORM(4, "平台"),
|
||||
// REFERENCE(5, "团长")
|
||||
final role = imUserInfoController?.role.value;
|
||||
if (role == 4) {
|
||||
return Row(children: [
|
||||
SizedBox(width: 8),
|
||||
//
|
||||
InkWell(
|
||||
onTap: () => qrcodeAlertDialog(context),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withAlpha(176),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.qr_code_outlined,
|
||||
size: 18,
|
||||
color: FStyle.secondaryColor,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
'团长邀请码',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: FStyle.secondaryColor, // 彩色文字
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return const SizedBox();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -912,7 +856,11 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
// '已售${Utils.graceNumber(int.tryParse(vlogLikeCount?.toString() ?? '0') ?? 0)}',
|
||||
Column(children: [Text('${Utils.graceNumber(vlogLikeCount)}', style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)), SizedBox(height: 3.0), Text('获赞')]),
|
||||
Column(children: [
|
||||
Text(Utils.graceNumber(vlogLikeCount), style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
|
||||
SizedBox(height: 3.0),
|
||||
Text('获赞')
|
||||
]),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
// 互相关注
|
||||
|
125
lib/pages/my/merchant/balance/balance.dart
Normal file
125
lib/pages/my/merchant/balance/balance.dart
Normal file
@ -0,0 +1,125 @@
|
||||
// 钱包页面
|
||||
import 'package:easy_refresh/easy_refresh.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/IM/im_service.dart';
|
||||
import 'package:loopin/behavior/custom_scroll_behavior.dart';
|
||||
import 'package:loopin/pages/my/merchant/balance/controller.dart';
|
||||
|
||||
class Balance extends StatefulWidget {
|
||||
const Balance({super.key});
|
||||
|
||||
@override
|
||||
State<Balance> createState() => _BalanceState();
|
||||
}
|
||||
|
||||
class _BalanceState extends State<Balance> {
|
||||
final controller = Get.put(BalanceController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("我的钱包")),
|
||||
body: ScrollConfiguration(
|
||||
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
|
||||
child: Column(
|
||||
children: [
|
||||
// 上半部分:余额 + 充值
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
color: Colors.blueAccent,
|
||||
width: double.infinity,
|
||||
child: Obx(() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"钱包余额",
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
"¥ ${controller.balance.value.toStringAsFixed(2)}",
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
ElevatedButton(
|
||||
onPressed: () => controller.recharge(100.0),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
child: const Text("充值 100 元"),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
// 下半部分:流水记录分页列表
|
||||
Expanded(
|
||||
child: Obx(() {
|
||||
return EasyRefresh.builder(
|
||||
callLoadOverOffset: 20, //触底距离
|
||||
callRefreshOverOffset: 20, // 下拉距离
|
||||
header: ClassicHeader(
|
||||
dragText: '下拉刷新',
|
||||
armedText: '释放刷新',
|
||||
readyText: '加载中...',
|
||||
processingText: '加载中...',
|
||||
processedText: '加载完成',
|
||||
failedText: '加载失败,请重试',
|
||||
messageText: '最后更新于 %T',
|
||||
),
|
||||
footer: ClassicFooter(
|
||||
dragText: '加载更多',
|
||||
armedText: '释放加载',
|
||||
readyText: '加载中...',
|
||||
processingText: '加载中...',
|
||||
processedText: controller.hasMore.value ? '加载完成' : '没有更多了~',
|
||||
failedText: '加载失败,请重试',
|
||||
messageText: '最后更新于 %T',
|
||||
succeededIcon: controller.hasMore.value ? Icon(Icons.check_circle, color: Colors.green) : Icon(Icons.warning, color: Colors.orange),
|
||||
),
|
||||
onRefresh: () async {
|
||||
await controller.getData(reset: true);
|
||||
},
|
||||
onLoad: () async {
|
||||
if (controller.hasMore.value) {
|
||||
await controller.getData();
|
||||
}
|
||||
},
|
||||
childBuilder: (context, physics) {
|
||||
return ListView.builder(
|
||||
physics: physics,
|
||||
itemCount: controller.data.length,
|
||||
itemBuilder: (context, index) {
|
||||
final tx = controller.data[index];
|
||||
logger.w(tx.source);
|
||||
|
||||
return ListTile(
|
||||
title: Text(tx.source),
|
||||
subtitle: Text(tx.createTime),
|
||||
trailing: Text(
|
||||
"变动金额:${tx.changeType == 1 ? '+' : '-'}${tx.changeAmount}", // 变动金额
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: tx.changeType == 1 ? Colors.green : Colors.red,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
56
lib/pages/my/merchant/balance/controller.dart
Normal file
56
lib/pages/my/merchant/balance/controller.dart
Normal file
@ -0,0 +1,56 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:loopin/pages/my/merchant/balance/model.dart';
|
||||
|
||||
class BalanceController extends GetxController {
|
||||
/// 钱包余额
|
||||
final balance = 0.0.obs;
|
||||
|
||||
final data = <AccountBill>[].obs;
|
||||
|
||||
int currentPage = 1;
|
||||
|
||||
final isLoading = false.obs;
|
||||
|
||||
/// 是否还有更多
|
||||
var hasMore = true.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getData(reset: true);
|
||||
}
|
||||
|
||||
/// 充值
|
||||
void recharge(double amount) {
|
||||
balance.value += amount;
|
||||
// 同时加一条流水
|
||||
}
|
||||
|
||||
/// 分页数据
|
||||
Future<void> getData({bool reset = false}) async {
|
||||
if (isLoading.value) return;
|
||||
isLoading.value = true;
|
||||
|
||||
if (reset) {
|
||||
currentPage = 1;
|
||||
data.clear();
|
||||
hasMore.value = true;
|
||||
}
|
||||
|
||||
await Future.delayed(const Duration(seconds: 3)); // 模拟网络延迟
|
||||
|
||||
List<AccountBill> newData = List.generate(
|
||||
10,
|
||||
(index) => AccountBill(id: index),
|
||||
);
|
||||
|
||||
data.addAll(newData);
|
||||
currentPage++;
|
||||
|
||||
if (currentPage > 3) {
|
||||
hasMore.value = false;
|
||||
}
|
||||
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
49
lib/pages/my/merchant/balance/model.dart
Normal file
49
lib/pages/my/merchant/balance/model.dart
Normal file
@ -0,0 +1,49 @@
|
||||
class AccountBill {
|
||||
final int id;
|
||||
final int? memberId;
|
||||
final int? accountId;
|
||||
final double moneyBalance; // 当前余额
|
||||
final double beforeBalance; // 变动前余额
|
||||
final double afterBalance; // 变动后余额
|
||||
final double changeAmount; // 变动金额
|
||||
final int changeType; // 变动类型(1收入 2支出)
|
||||
final String changeDesc; // 变动描述
|
||||
final String source; // 变动来源
|
||||
final String createTime; // 创建时间
|
||||
final int createBy;
|
||||
final String updateTime;
|
||||
|
||||
AccountBill({
|
||||
required this.id,
|
||||
this.memberId,
|
||||
this.accountId,
|
||||
this.moneyBalance = 0.0,
|
||||
this.beforeBalance = 0.0,
|
||||
this.afterBalance = 0.0,
|
||||
this.changeAmount = 0.0,
|
||||
this.changeType = 1,
|
||||
this.changeDesc = '',
|
||||
this.source = '未知来源',
|
||||
this.createTime = '',
|
||||
this.createBy = 0,
|
||||
this.updateTime = '',
|
||||
});
|
||||
|
||||
factory AccountBill.fromJson(Map<String, dynamic> json) {
|
||||
return AccountBill(
|
||||
id: json['id'] ?? 0,
|
||||
memberId: json['member_id'],
|
||||
accountId: json['account_id'],
|
||||
moneyBalance: (json['money_balance'] as num?)?.toDouble() ?? 0.0,
|
||||
beforeBalance: (json['before_balance'] as num?)?.toDouble() ?? 0.0,
|
||||
afterBalance: (json['after_balance'] as num?)?.toDouble() ?? 0.0,
|
||||
changeAmount: (json['change_amount'] as num?)?.toDouble() ?? 0.0,
|
||||
changeType: json['change_type'] ?? 1,
|
||||
changeDesc: json['change_desc'] ?? '',
|
||||
source: json['source'] ?? '未知来源',
|
||||
createTime: json['create_time'] ?? '',
|
||||
createBy: json['create_by'] ?? 0,
|
||||
updateTime: json['update_time'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user