This commit is contained in:
abu 2025-09-18 16:13:37 +08:00
parent a000a4aeea
commit 27001b12d6
9 changed files with 467 additions and 224 deletions

View File

@ -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(

View File

@ -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)),
),

View File

@ -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(),
],
),

View File

@ -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),

View File

@ -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,10 +228,10 @@ 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))),
],
);
},
);
}
}
}

View File

@ -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 {
//

View 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,
),
),
);
},
);
},
);
}),
),
],
),
),
);
}
}

View 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;
}
}

View 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'] ?? '',
);
}
}