初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
+212
View File
@@ -0,0 +1,212 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_model/comment/comment_model.dart';
import 'package:hgdj/hj_model/comment/reply_model.dart';
import 'package:hgdj/hj_page/comment/comment_input_view.dart';
import 'package:hgdj/hj_utils/api_service/comment_service.dart';
import 'package:hgdj/hj_utils/api_service/common_service.dart';
import 'package:hgdj/hj_utils/date_time_util.dart';
import 'package:hgdj/tools_base/debug_log.dart';
import 'package:hgdj/tools_base/toast.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../hj_model/banner/comment_top_banner_model.dart';
import '../../hj_model/comment/comment_list_res.dart';
import '../../tools_base/file_upload/file_upload_tool.dart';
import '../../tools_base/file_upload/upload_result_model.dart';
mixin CommentMixin on GetxController {
final comments = <CommentModel>[];
final commentController = TextEditingController();
Function(int)? totalCallback;
CommentModel? replyComment;
ReplyModel? replyCommentModel;
int page = 1;
String? hintText;
Rx<String?> selectedImagePath = Rx<String?>(null);
RefreshController? refreshCtr;
final quickSearchList = <CommentLink>[];
final commentTopBanners = <CommentTopBannerModel>[];
String? id;
String? objType;
RxBool isSendingMsg = false.obs;
@override
void onClose() {
commentController.dispose();
super.onClose();
}
Future sendComment() async {
String content = commentController.text;
if (content.isEmpty) {
showToast('请输入评论内容哦~');
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 {
if (replyComment != null) {
// 回复评论
final res = await CommentService.sendReply(
id,
2,
content,
rid: replyCommentModel?.id,
cid: replyComment?.id,
toUserID: replyCommentModel?.toUserID,
objType: objType,
image: sendImagePath,
);
if (res != null) {
replyComment?.replies ??= [];
replyComment?.replies?.insert(0, res);
replyComment?.commCount = replyComment?.replies?.length ?? 0;
replyComment = null;
replyCommentModel = null;
hintText = null;
showToast('已提交,审核通过后将展示');
}
update();
} else {
// 评论
final res = await CommentService.sendComment(
id,
1,
content,
objType ?? '',
image: sendImagePath,
);
if (res == null) {
hintText = null;
} else {
showToast('已提交,审核通过后将展示');
hintText = null;
//插在第一条普通评论前面,置顶那几条不动
final insertIndex =
comments.indexWhere((e) => !e.isHideLikeOrComment);
comments.insert(
insertIndex == -1 ? comments.length : insertIndex, res);
}
update();
}
} catch (e) {
debugLog(e);
}
selectedImagePath.value = null;
commentController.text = "";
isSendingMsg.value = false;
}
// isSend: true 点击了发送按钮, 如果没有发送内容弹键盘, 有内容直接发送
readyReplyComment(CommentModel? comment,
{ReplyModel? replyModel, bool? isSend}) async {
replyComment = comment;
replyCommentModel = replyModel;
if (replyModel != null) {
hintText = '回复:${replyModel.userName ?? ''}';
}
if (comment != null && hintText == null) {
hintText = '回复:${comment.userName ?? ''}';
}
if (isSend == true && commentController.text.isNotEmpty) {
update();
sendComment();
} else {
final result = await Get.bottomSheet(
CommentInputView(
hint: hintText,
textCtr: commentController,
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();
sendComment();
}
}
}
// 获取评论
Future fetchComments(String id, {bool isRefresh = false}) async {
try {
if (isRefresh) {
page = 1;
}
final currentT = DateTimeUtil.format2utc(DateTime.now()) ?? "";
final result =
await CommentService.getCommentList(id, currentT, page, 20);
totalCallback?.call(result?.total ?? 0);
refreshCtr?.refreshCompleted();
refreshCtr?.loadComplete();
if (!(result?.hasNext ?? false)) {
refreshCtr?.loadNoData();
}
if (page == 1) {
comments.clear();
quickSearchList.clear();
// 首屏并行拉置顶 Banner;失败不影响评论列表
_fetchCommentTopBanners();
}
comments.addAll(result?.list ?? []);
if (page == 1) {
quickSearchList.addAll(result?.quickSearchList ?? []);
}
page += 1;
for (final e in comments) {
e.hasMoreReply = (e.commCount ?? 0) > (e.replies?.length ?? 0);
}
} catch (e) {
refreshCtr?.refreshCompleted();
refreshCtr?.loadComplete();
debugLog(e);
}
update();
}
/// 评论区置顶 Bannerscene=COMMENT_TOP
Future<void> _fetchCommentTopBanners() async {
try {
final list = await CommonService.fetchBannerList(scene: 'COMMENT_TOP');
commentTopBanners
..clear()
..addAll(list);
update();
} catch (e) {
debugLog(e);
}
}
/// 首条置顶评论下标:官方评论或带内外链的置顶样式评论
int get topPinnedCommentIndex {
for (int i = 0; i < comments.length; i++) {
final c = comments[i];
if (c.isOfficial || c.isHideLikeOrComment) return i;
}
return -1;
}
}