初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
@@ -0,0 +1,173 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/assets_tool/app_colors.dart';
import 'package:hgdj/hj_utils/pay/pay_manager.dart';
import 'package:hgdj/extension/extensions.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/routers/jump_router.dart';
import 'package:hgdj/tools_base/global_store/store.dart';
import 'package:hgdj/tools_base/widget/sheet_handle_bar.dart';
import 'package:provider/provider.dart';
import '../model/im_group_list_model.dart';
class GroupBuyBottomSheet extends StatefulWidget {
final IMGroupItemModel groupModel;
const GroupBuyBottomSheet({super.key, required this.groupModel});
@override
State<GroupBuyBottomSheet> createState() => _GroupBuyBottomSheetState();
}
class _GroupBuyBottomSheetState extends State<GroupBuyBottomSheet> {
@override
void initState() {
super.initState();
globalStore.updateUserInfo();
globalStore.refreshWallet();
}
@override
Widget build(BuildContext context) {
return Consumer<GlobalStore>(
builder: (_, store, __) {
final enough =
(store.wallet?.amount ?? 0) >= (widget.groupModel.price ?? 0);
return _buildNormal(enough, store);
},
);
}
Widget _buildNormal(bool enough, GlobalStore store) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 18),
decoration: BoxDecoration(
color: AppColors.primaryColor,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SheetHandleBar(),
18.sizeBoxH,
Text(
'购买',
style: TextStyle(
color: Color(0xE5ffffff),
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
36.sizeBoxH,
Row(
children: [
Text(
'解锁群聊',
style: TextStyle(
color: Color(0xE5ffffff),
fontSize: 14,
),
),
Spacer(),
GestureDetector(
onTap: () => pushToWalletPage(tabPosition: 1),
child: Row(
children: [
Text(
'${widget.groupModel.price ?? 0} 金币',
style:
TextStyle(color: AppColors.actionRed, fontSize: 14),
),
],
),
)
],
),
18.sizeBoxH,
0.5.line,
18.sizeBoxH,
Row(
children: [
Text(
'我的金币',
style: TextStyle(
color: Color(0xE5ffffff),
fontSize: 14,
),
),
Spacer(),
Row(
children: [
Text(
'${GlobalStore().wallet?.amount?.toDouble().fixed(2) ?? 0}',
style: TextStyle(
color: Color(0xE5ffffff),
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
12.sizeBoxW,
InkWell(
enableFeedback: false,
onTap: () => pushToWalletPage(tabPosition: 1),
child: Text(
'充值',
style: TextStyle(
color: Color(0xffA4634D),
fontSize: 14,
fontWeight: FontWeight.w400,
decoration: TextDecoration.underline,
decorationColor: Color(0xffA4634D),
),
),
),
],
),
],
),
18.sizeBoxH,
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => _doPayAction(enough),
child: Container(
width: double.infinity,
height: 44,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: AppColors.actionRed,
),
alignment: Alignment.center,
child: Text(
enough
? '${widget.groupModel.price ?? 0} 金币/立即支付'
: '余额不足,前往充值',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500),
),
),
),
],
),
);
}
void _doPayAction(bool enough) async {
if (!enough) {
await pushToWalletPage(tabPosition: 1);
return;
}
await PayManager().buy(
widget.groupModel.id,
ProductType.group,
source: 'group_buy',
onSuccess: (data) {
globalStore.refreshWallet();
Get.back(result: true);
},
);
}
}
@@ -0,0 +1,136 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/tools_base/debug_log.dart';
import 'package:hgdj/tools_base/global_store/store.dart';
import 'package:hgdj/tools_base/toast.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../../../hj_utils/api_service/group_service.dart';
import '../../../../tools_base/file_upload/file_upload_tool.dart';
import '../../../../tools_base/file_upload/upload_result_model.dart';
import '../../../comment/comment_input_view.dart';
import '../model/im_group_list_model.dart';
import '../model/im_message_resp.dart';
class GroupChatDetailLogic extends GetxController {
final IMGroupItemModel model;
GroupChatDetailLogic(this.model);
int pageNum = 1;
List<IMMessageModel>? msgList;
RefreshController? refreshController;
TextEditingController textEditController = TextEditingController();
Rx<String?> selectedImagePath = Rx<String?>(null);
RxBool isSendingMsg = false.obs;
@override
void onReady() {
refreshData();
super.onReady();
}
void refreshData() {
_loadData();
}
void loadMoreData() {
_loadData(page: pageNum + 1);
}
void _loadData({int page = 1, int size = 20}) async {
try {
final retResp = await GroupService.getMessages(model.groupId, page, size);
pageNum = page;
msgList ??= [];
if (pageNum == 1) {
msgList?.clear();
}
msgList?.addAll(retResp.list ?? []);
retResp.hasNext == true
? refreshController?.loadComplete()
: refreshController?.loadNoData();
} catch (e) {
debugLog(e);
refreshController?.loadComplete();
}
refreshController?.refreshCompleted();
update();
}
Future readySendMsg({bool? isSend}) async {
if (isSend == true &&
(textEditController.text.isNotEmpty ||
selectedImagePath.value?.isNotEmpty == true)) {
// 点击发送按钮有内容,直接发送内容, 否则弹出输入框
sendMsgEvent();
} else {
final result = await Get.bottomSheet(
CommentInputView(
hint: "请输入消息",
textCtr: textEditController,
imgPath: selectedImagePath.value,
onImgChange: (value) => selectedImagePath.value = value,
),
backgroundColor: Colors.transparent,
barrierColor: Colors.transparent,
enableDrag: false,
settings: RouteSettings(name: CommentInputView.routeName),
useRootNavigator: true,
);
if (result == true) {
update();
}
sendMsgEvent();
}
}
Future sendMsgEvent() async {
if (textEditController.text.isEmpty &&
selectedImagePath.value?.isNotEmpty != true) {
showToast("请输入消息内容");
return;
}
if (isSendingMsg.value) return;
isSendingMsg.value = true;
String? sendImagePath;
if (selectedImagePath.value?.isNotEmpty == true) {
try {
ImageUploadResultModel? imgResult =
await FileUploadTool().uploadImage(selectedImagePath.value!);
sendImagePath = imgResult?.coverImg ?? "";
if (sendImagePath.isEmpty) {
isSendingMsg.value = false;
showToast("图片上传失败!");
return;
}
} catch (e) {
debugLog(e);
isSendingMsg.value = false;
showToast("图片上传失败!");
return;
}
}
try {
var ret = await GroupService.sendMessage(
model.groupId, textEditController.text, sendImagePath);
if (ret.isSuccess) {
textEditController.text = "";
selectedImagePath.value = null;
showToast("消息已发送");
if (ret.data is Map && (ret.data['message'] is Map)) {
IMMessageModel sendModel =
IMMessageModel.fromJson(ret.data['message']);
sendModel.portrait = globalStore.meInfo?.portrait;
sendModel.name = globalStore.meInfo?.name;
msgList?.insert(0, sendModel);
update();
}
}
} catch (e) {
showToast("消息发送失败!");
debugLog(e);
}
isSendingMsg.value = false;
}
}
@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_page/comment/widget/comment_foot_view.dart';
import 'package:hgdj/tools_base/refresh/pull_refresh.dart';
import '../model/im_group_list_model.dart';
import 'soul_group_detail_logic.dart';
import 'widget/chat_item_cell.dart';
class GroupChatDetailPage extends StatelessWidget {
final IMGroupItemModel model;
const GroupChatDetailPage(this.model, {super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<GroupChatDetailLogic>(
global: false,
init: GroupChatDetailLogic(model),
builder: (logic) {
return Scaffold(
appBar: AppBar(
title: Text(model.name ?? ""),
),
body: Column(
children: [
Expanded(
child: pullYsRefresh(
onInit: (ctr) => logic.refreshController = ctr,
onRefresh: (ctr) => logic.refreshData(),
onLoading: (ctr) => logic.loadMoreData(),
child: ListView.builder(
itemCount: logic.msgList?.length ?? 0,
reverse: true,
padding: EdgeInsets.only(bottom: 12, top: 12),
itemBuilder: (context, index) {
return ChatItemCell(model: logic.msgList![index]);
},
),
),
),
Obx(
() => CommentFootView(
imgPath: logic.selectedImagePath.value,
isSending: logic.isSendingMsg.value,
onImgChange: (value) => logic.selectedImagePath.value = value,
onComment: (isSend) => logic.readySendMsg(isSend: isSend),
textCtr: logic.textEditController,
),
),
],
),
);
},
);
}
}
@@ -0,0 +1,276 @@
import 'package:flutter/material.dart';
import 'package:hgdj/assets_tool/app_colors.dart';
import 'package:hgdj/routers/jump_router.dart';
import 'package:hgdj/tools_base/widget/net_image_widget.dart';
import '../../../../../tools_base/global_store/store.dart';
import 'package:hgdj/tools_base/widget/image_browser_page.dart';
import '../../model/im_message_resp.dart';
class ChatItemCell extends StatefulWidget {
final IMMessageModel? model;
ChatItemCell({super.key, this.model});
@override
State<StatefulWidget> createState() {
return _ChatItemCellState();
}
}
class _ChatItemCellState extends State<ChatItemCell> {
bool get isImg => widget.model?.image?.isNotEmpty == true;
bool get isMe => globalStore.isMe(widget.model?.uid);
double imageWidth = 173;
@override
void initState() {
super.initState();
}
void _showImageScan(String imageUrl) {
if (imageUrl.isNotEmpty) {
ImageBrowserPage.open([widget.model?.image ?? '']);
}
}
@override
Widget build(BuildContext context) {
if (isMe) {
return _buildRightStyle();
} else {
return _buildLeftStyle();
}
}
Widget _buildLeftStyle() {
return Container(
padding: EdgeInsets.fromLTRB(0, 12, 0, 6),
child: Column(
children: [
_buildTime(),
Container(
padding: EdgeInsets.fromLTRB(16, 0, 50, 0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
pushToPersonCenter(widget.model?.uid);
},
child: SizedBox(
width: 40,
height: 40,
child: NetworkImageLoader(
imageUrl: widget.model?.portrait ?? "",
width: 40,
height: 40,
borderRadius: 20,
),
),
),
SizedBox(width: 12),
Flexible(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.model?.name ?? "",
style: TextStyle(
color: Colors.white.withValues(alpha: 0.9),
fontSize: 14,
),
),
SizedBox(height: 10),
if (widget.model?.content?.isNotEmpty == true)
Container(
padding: EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
margin: EdgeInsets.only(top: 5),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.05),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
topRight: Radius.circular(12),
topLeft: Radius.circular(2)),
),
child: Text(
widget.model?.content ?? "",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
),
if (isImg)
InkWell(
enableFeedback: false,
onTap: () {
_showImageScan(widget.model?.image ?? "");
},
child: Container(
margin: EdgeInsets.only(top: 5),
alignment: Alignment.centerLeft,
constraints: BoxConstraints(maxWidth: 173),
child: _buildImageWidget(isLeft: true),
),
),
],
),
),
],
),
),
],
),
);
}
Widget _buildRightStyle() {
return Container(
padding: EdgeInsets.fromLTRB(0, 12, 0, 6),
child: Column(
children: [
_buildTime(),
Container(
padding: EdgeInsets.fromLTRB(50, 0, 16, 0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
widget.model?.name ?? "",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
SizedBox(height: 10),
if (widget.model?.content?.isNotEmpty == true)
Container(
padding: EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
margin: EdgeInsets.only(top: 5),
decoration: BoxDecoration(
color: Color(0xff1DC194),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
topLeft: Radius.circular(12),
topRight: Radius.circular(4)),
),
child: Text(
widget.model?.content ?? "",
style: TextStyle(
color: Color(0xff141414),
fontSize: 14,
),
),
),
if (isImg)
InkWell(
enableFeedback: false,
onTap: () {
_showImageScan(widget.model?.image ?? "");
},
child: Container(
margin: EdgeInsets.only(top: 5),
alignment: Alignment.centerRight,
constraints: BoxConstraints(maxWidth: 173),
child: _buildImageWidget(isLeft: false),
),
),
],
),
),
SizedBox(width: 12),
GestureDetector(
onTap: () {},
child: SizedBox(
width: 40,
height: 40,
child: NetworkImageLoader(
imageUrl: widget.model?.portrait,
width: 40,
height: 40,
borderRadius: 20,
),
),
),
],
),
),
],
),
);
}
Widget _buildImageWidget({bool isLeft = false}) {
return Stack(
children: [
NetworkImageLoader(
imageUrl: widget.model?.image ?? "",
width: imageWidth,
imgBorderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12),
topRight: Radius.circular(isLeft ? 12 : 0),
topLeft: Radius.circular(isLeft ? 0 : 12),
),
),
if (isLeft)
Positioned(
bottom: 12,
left: 0,
right: 0,
child: Container(
alignment: Alignment.bottomCenter,
child: Container(
width: 72,
height: 26,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: AppColors.actionRed,
),
child: Text(
'查看原图',
style: TextStyle(fontSize: 12, color: Colors.white),
),
),
),
),
],
);
}
Widget _buildTime() {
// if (widget.model?.isShowTime == true) {
// return Container(
// margin: EdgeInsets.fromLTRB(0, 12, 0, 12),
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 2),
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(30),
// // color: Color(0xfff7f7f7).withValues(alpha: 0.42),
// // ),
// child: Text(
// widget.model?.createAtDesc ?? "",
// style: TextStyle(
// color: Color(0xff666666),
// fontSize: 12,
// ),
// ),
// );
// }
return SizedBox();
}
}
@@ -0,0 +1,46 @@
import 'package:get/get.dart';
import 'package:hgdj/tools_base/debug_log.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../../hj_utils/api_service/group_service.dart';
import 'model/im_group_list_model.dart';
class GroupChatLogic extends GetxController {
int pageNum = 1;
List<IMGroupItemModel>? groupList;
RefreshController? refreshController;
@override
void onReady() {
refreshData();
super.onReady();
}
void refreshData() {
_loadData();
}
void loadMoreData() {
_loadData(page: pageNum + 1);
}
void _loadData({int page = 1}) async {
try {
final retResp = await GroupService.getList(page);
pageNum = page;
groupList ??= [];
if (pageNum == 1) {
groupList?.clear();
}
groupList?.addAll(retResp?.list ?? []);
retResp?.hasNext == true
? refreshController?.loadComplete()
: refreshController?.loadNoData();
} catch (e) {
debugLog(e);
refreshController?.loadComplete();
}
refreshController?.refreshCompleted();
update();
}
}
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_page/main_page/provider/bottom_bar_provider.dart';
import 'package:hgdj/hj_utils/const.dart';
import 'package:hgdj/tools_base/banner/ads_grid_view_widget.dart';
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
import 'package:hgdj/tools_base/refresh/pull_refresh.dart';
import 'group_chat_logic.dart';
import 'widget/chat_group_cell.dart';
class GroupChatPage extends StatelessWidget {
const GroupChatPage({super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<GroupChatLogic>(
global: false,
init: GroupChatLogic(),
builder: (logic) {
return pullYsRefresh(
onInit: (ctr) => logic.refreshController = ctr,
onRefresh: (ctr) => logic.refreshData(),
onLoading: (ctr) => logic.loadMoreData(),
child: CustomScrollView(
controller:
CommunityBottomProvider().scrollCtr(MediaStyle.GroupChat, 0),
slivers: [
SliverToBoxAdapter(
child: AdsGridViewWidget(
6,
accordingAdsType: true,
padding: EdgeInsets.fromLTRB(16, 12, 16, 18),
),
),
if (logic.groupList == null)
SliverToBoxAdapter(child: LoadingCenterWidget(height: 400))
else if (logic.groupList!.isEmpty)
SliverToBoxAdapter(
child: SizedBox(
height: 400,
child: CErrorWidget(
retryOnTap: () => logic.refreshData(),
),
),
)
else
SliverList.builder(
itemBuilder: (ctx, index) =>
ChatGroupCell(logic.groupList![index]),
itemCount: logic.groupList!.length,
),
],
),
);
},
);
}
}
@@ -0,0 +1,87 @@
class IMGroupListModel {
bool? hasNext;
List<IMGroupItemModel>? list;
int? total;
IMGroupListModel({this.hasNext, this.list, this.total});
IMGroupListModel.fromJson(Map<String, dynamic> json) {
hasNext = json['hasNext'];
if (json['list'] != null) {
list = <IMGroupItemModel>[];
json['list'].forEach((v) {
list!.add(new IMGroupItemModel.fromJson(v));
});
}
total = json['total'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['hasNext'] = this.hasNext;
if (this.list != null) {
data['list'] = this.list!.map((v) => v.toJson()).toList();
}
data['total'] = this.total;
return data;
}
}
class IMGroupItemModel {
String? cover;
String? createdAt;
///成员数量(假的)
int? fakeMemberNum;
int? groupId;
String? id;
///成员数量(真实)
int? memberNum;
String? name;
///加入群聊价格 0-免费
int? price;
String? summary;
String? updatedAt;
IMGroupItemModel(
{this.cover,
this.createdAt,
this.fakeMemberNum,
this.groupId,
this.id,
this.memberNum,
this.name,
this.price,
this.summary,
this.updatedAt});
IMGroupItemModel.fromJson(Map<String, dynamic> json) {
cover = json['cover'];
createdAt = json['createdAt'];
fakeMemberNum = json['fakeMemberNum'];
groupId = json['groupId'];
id = json['id'];
memberNum = json['memberNum'];
name = json['name'];
price = json['price'];
summary = json['summary'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['cover'] = this.cover;
data['createdAt'] = this.createdAt;
data['fakeMemberNum'] = this.fakeMemberNum;
data['groupId'] = this.groupId;
data['id'] = this.id;
data['memberNum'] = this.memberNum;
data['name'] = this.name;
data['price'] = this.price;
data['summary'] = this.summary;
data['updatedAt'] = this.updatedAt;
return data;
}
}
@@ -0,0 +1,46 @@
class IMMessageResp {
bool? hasNext;
List<IMMessageModel>? list;
int? total;
IMMessageResp({this.hasNext, this.list, this.total});
IMMessageResp.fromJson(Map<String, dynamic> json) {
hasNext = json['hasNext'];
if (json['list'] is List) {
list = <IMMessageModel>[];
json['list'].forEach((v) {
list!.add(IMMessageModel.fromJson(v));
});
}
total = json['total'];
}
}
class IMMessageModel {
String? id;
int? groupId;
int? uid;
String? name;
String? gender;
String? portrait;
String? content;
String? image;
String? createdAt;
IMMessageModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
groupId = json['groupId'];
uid = json['uid'];
name = json['name'];
// gender = json['gender'];
portrait = json['portrait'];
content = json['content'];
image = json['image'];
createdAt = json['createdAt'];
}
}
@@ -0,0 +1,147 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/tools_base/toast.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/tools_base/debug_log.dart';
import 'package:hgdj/tools_base/global_store/store.dart';
import 'package:hgdj/tools_base/loading/loading_alert_widget.dart';
import '../../../../alert/mine/vip_level_dialog.dart';
import '../../../../assets_tool/app_colors.dart';
import '../../../../hj_utils/api_service/group_service.dart';
import '../../../../tools_base/widget/header_widget.dart';
import '../alert/group_buy_bottom_sheet.dart';
import '../detail/soul_group_detail_page.dart';
import '../model/im_group_list_model.dart';
import 'package:hgdj/extension/extensions.dart';
class ChatGroupCell extends StatefulWidget {
final IMGroupItemModel model;
ChatGroupCell(this.model, {super.key});
@override
State<StatefulWidget> createState() {
return _ChatGroupCellState();
}
}
class _ChatGroupCellState extends State<ChatGroupCell> {
IMGroupItemModel get model => widget.model;
void _addGroupEvent() async {
if (!globalStore.isVIPTopLevel) {
showVipLevelDialog('本内容需要开通至尊VIP会员\n\n开通会员 即可畅享高级群聊特权');
return;
}
try {
LoadingAlertWidget.show();
final retResp = await GroupService.getHasJoin(model.groupId);
LoadingAlertWidget.cancel();
if (retResp.isSuccess) {
int status = retResp.data['status']; // 0-已被禁言 1-可发言 2-未加入
if (status == 0) {
showToast("您已被禁言");
} else if (status == 1) {
Get.to(GroupChatDetailPage(model));
} else if (status == 2) {
var ret = await Get.bottomSheet(
GroupBuyBottomSheet(groupModel: widget.model));
if (ret == true) {
Get.to(GroupChatDetailPage(model));
}
} else {
showToast("群未知状态");
}
}
} catch (e) {
LoadingAlertWidget.cancel();
showToast("网络数据异常");
debugLog(e);
}
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(left: 16, right: 16, bottom: 12),
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: .05),
borderRadius: BorderRadius.circular(6),
),
child: InkWell(
enableFeedback: false,
onTap: _addGroupEvent,
child: Row(
children: [
HeaderWidget(
headPath: model.cover ?? '',
level: 1,
headWidth: 64,
headHeight: 64,
isCircle: false,
radius: 32,
),
12.sizeBoxW,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
model.name ?? '',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500),
),
2.sizeBoxH,
Text(
model.summary ?? '',
maxLines: 1,
style: TextStyle(
color: Colors.white.withValues(alpha: 0.55),
fontSize: 12,
),
),
6.sizeBoxH,
Row(
children: [
Text(
'ID: ${model.groupId ?? 0} ${model.fakeMemberNum.countStr}人在玩',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.55),
fontSize: 12,
),
),
Spacer(),
GestureDetector(
onTap: _addGroupEvent,
child: Container(
width: 52,
height: 24,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: AppColors.actionRed),
child: Text(
'加入群聊',
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
),
),
),
],
),
],
),
),
],
),
),
);
}
}