初始化

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,66 @@
import 'package:get/get.dart';
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/hj_utils/api_service/mine_service.dart';
import 'package:hgdj/tools_base/toast.dart';
import 'mine_publish_sub_logic.dart';
class MinePublishLogic extends GetxController {
MinePublishLogic();
List<VideoModel> checkedList = [];
List<VideoModel> dataSource = [];
void addChecked(VideoModel videoModel) {
checkedList.add(videoModel);
update();
}
void removeChecked(VideoModel videoModel) {
checkedList.remove(videoModel);
update();
}
void clearChecked() {
checkedList.clear();
update();
}
bool get isAllChecked {
if (dataSource.isEmpty || checkedList.isEmpty) {
return false;
}
return checkedList.length == dataSource.length;
}
bool get isEmptyChecked {
return checkedList.isEmpty;
}
void selectAllOrNot() {
if (isAllChecked) {
checkedList.clear();
} else {
checkedList.clear();
checkedList.addAll(dataSource);
}
update();
}
void delete() async {
if (checkedList.isEmpty) {
showToast('请选择要删除的项');
return;
}
String resultMsg = await MineService.deletePublishes(
ids: checkedList.map((e) => e.id ?? '').toList());
if (resultMsg.isEmpty) {
checkedList.clear();
update();
Get.find<MinePublishSubLogic>(tag: '2').loadData(isRefresh: true);
showToast('删除成功');
} else {
showToast(resultMsg);
}
}
}
@@ -0,0 +1,315 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_model/user/wallet_model.dart';
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/tools_base/global_store/store.dart';
import 'package:hgdj/tools_base/indicator/custom_tab_indicator.dart';
import 'package:hgdj/tools_base/widget/keep_alive_widget.dart';
import 'package:provider/provider.dart';
import '../../../hj_utils/widget_util.dart';
import '../../home/widget/publist_entry_alert.dart';
import '../make_money/mine_withdrawal_record_page.dart';
import '../make_money/withdrawal_page.dart';
import 'mine_publish_main_logic.dart';
import 'mine_publish_sub_logic.dart';
import 'mine_publish_sub_page.dart';
///我发布的帖子
class MinePublishPostPage extends StatefulWidget {
const MinePublishPostPage({super.key});
@override
State<StatefulWidget> createState() {
return _MinePublishPostPageState();
}
}
class _MinePublishPostPageState extends State<MinePublishPostPage>
with TickerProviderStateMixin {
final tabs = ['已发布', '待审核', '未通过'];
WalletModel? get wallet => globalStore.wallet;
late final tabCtr = TabController(length: tabs.length, vsync: this);
bool inEdit = false;
@override
void initState() {
super.initState();
tabCtr.addListener(_onTabChanged);
}
@override
void dispose() {
tabCtr.removeListener(_onTabChanged);
tabCtr.dispose();
super.dispose();
}
void _onTabChanged() {
setState(() {});
}
void _setSelectedTabDatas() {
final logic = Get.find<MinePublishLogic>();
if (tabCtr.index == 2) {
logic.dataSource = List<VideoModel>.from(
Get.find<MinePublishSubLogic>(tag: '2').dataList ?? []);
} else {
logic.dataSource = [];
}
logic.update();
}
@override
Widget build(BuildContext context) {
return GetBuilder(
init: MinePublishLogic(),
builder: (controller) {
return Scaffold(
appBar: AppBar(
title: Text("创作中心",
style: textStyle(18, Color(0xE5FFFFFF), FontWeight.w600)),
actions: [
Visibility(
visible: tabCtr.index == 2,
child: TextButton(
onPressed: () {
if (inEdit) {
controller.clearChecked();
} else {
_setSelectedTabDatas();
}
setState(() => inEdit = !inEdit);
},
child: Text(
inEdit ? '完成' : '编辑',
style: TextStyle(
color: Color(0xFF989898),
fontSize: 12,
),
),
),
)
],
),
body: Stack(
children: [
Column(
children: [
Consumer<GlobalStore>(
builder: (context, store, child) {
return Container(
margin: EdgeInsets.symmetric(
horizontal: 16, vertical: 18),
padding: EdgeInsets.fromLTRB(0, 14, 0, 22),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: Colors.white.withValues(alpha: .05),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
_buildItem(
'收益余额',
'${wallet?.income}',
'立即提现',
() => Get.to(WithdrawalPage()),
),
_buildItem(
'累计收益',
'${wallet?.vidIncome}',
'业绩明细',
() =>
Get.to(RecordsPage(RecordType.income)),
),
],
),
],
),
);
},
),
_buildTabbar(),
Expanded(child: _buildContent())
],
),
if (!inEdit)
Positioned(
right: 20,
bottom: 50,
child: PublishButton(
entry: PublishEntry.community,
),
),
if (inEdit)
Positioned(
left: 0,
right: 0,
height: 62,
bottom: MediaQuery.of(context).viewInsets.bottom,
child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Color(0xFF303030),
borderRadius: BorderRadius.circular(3),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
controller.selectAllOrNot();
},
child: Container(
width: 112,
height: 24,
alignment: Alignment.center,
child: Text(
controller.isAllChecked ? '取消全选' : '全选',
style: TextStyle(
color: Color(0x99FFFFFF), fontSize: 16),
),
),
),
Container(
width: 1,
height: 20,
color: Color(0x1AFFFFFF),
),
GestureDetector(
onTap: controller.isEmptyChecked
? null
: () {
controller.delete();
},
child: Container(
width: 112,
height: 38,
decoration: BoxDecoration(
color: Color(0xFFF52C56).withValues(
alpha: controller.isEmptyChecked ? 0.5 : 1),
borderRadius: BorderRadius.circular(3),
),
alignment: Alignment.center,
child: Text(
'删除(${controller.checkedList.length})',
style: TextStyle(
color: Colors.white.withValues(
alpha: controller.isEmptyChecked
? 0.5
: 1),
fontSize: 16),
),
),
),
],
),
),
),
],
));
},
);
}
_buildTabbar() {
return TabBar(
padding: const EdgeInsets.only(left: 12),
tabAlignment: TabAlignment.fill,
controller: tabCtr,
onTap: (index) {
if (index != 2 && inEdit) {
// 如果切换到非"未通过"标签页,强制退出编辑模式
setState(() {
inEdit = false;
Get.find<MinePublishLogic>().clearChecked();
});
}
},
tabs: List.generate(
tabs.length,
(index) => Padding(
padding: const EdgeInsets.only(top: 12, bottom: 4),
child: FittedBox(
child: Text(tabs[index]),
),
)),
isScrollable: false,
labelColor: Colors.white.withValues(alpha: .9),
labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
unselectedLabelColor: Colors.white.withValues(alpha: 0.35),
unselectedLabelStyle:
const TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
indicator: CustomIndicator(
width: 13,
height: 3,
borderRadius: BorderRadius.circular(2),
isGradient: true,
),
);
}
_buildItem(
String title, String count, String actionTitle, Function() action) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
title,
style: TextStyle(
color: Colors.white.withValues(alpha: .7),
fontWeight: FontWeight.w500,
fontSize: 14),
),
6.sizeBoxH,
Text(
count,
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w500, fontSize: 24),
),
6.sizeBoxH,
GestureDetector(
onTap: () => action.call(),
child: Container(
width: 72,
height: 25,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(13.5)),
color: Color(0xffF68804),
),
child: Text(
actionTitle,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 12.0),
),
),
),
],
);
}
// TabBarView 内容(外层调用处 line 134 已用 Expanded 包裹,这里不再套 Expanded,否则双 Expanded 冲突)
Widget _buildContent() {
return TabBarView(
controller: tabCtr,
physics: inEdit && tabCtr.index == 2
? const NeverScrollableScrollPhysics()
: null,
children: [
MinePublishSubPage(status: 1, inEdit: false).keepAlive,
MinePublishSubPage(status: 0, inEdit: false).keepAlive,
MinePublishSubPage(status: 2, inEdit: inEdit).keepAlive,
],
);
}
}
@@ -0,0 +1,23 @@
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/hj_utils/api_service/mine_service.dart';
import 'package:hgdj/tools_base/base_list_controller.dart';
class MinePublishSubLogic extends ListBaseLogic<VideoModel> {
final int status;
MinePublishSubLogic({required this.status});
@override
void onReady() {
super.onReady();
loadData();
}
void loadData({bool isRefresh = true}) =>
fetchData(isRefresh: isRefresh, fetch: _fetch);
Future<(List<VideoModel>?, bool)> _fetch(int page) async {
final res = await MineService.fetchPublishes(page: page, status: status);
return (res.list, res.hasNext ?? false);
}
}
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/hj_model/video_model.dart';
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
import 'package:hgdj/tools_base/refresh/pull_refresh.dart';
import '../../community/widget/community_post_widget.dart';
import 'mine_publish_main_logic.dart';
import 'mine_publish_sub_logic.dart';
typedef OnItemCheckCallback = void Function(
VideoModel videoModel, bool isChecked);
class MinePublishSubPage extends StatelessWidget {
final int status;
final bool inEdit;
final OnItemCheckCallback? onItemCheck;
const MinePublishSubPage(
{super.key, this.status = 0, this.inEdit = false, this.onItemCheck});
@override
Widget build(BuildContext context) {
final logic = Get.find<MinePublishLogic>();
return GetBuilder<MinePublishSubLogic>(
init: MinePublishSubLogic(status: status),
tag: status.toString(),
builder: (controller) {
return pullYsRefresh(
onInit: (refr) => controller.refreshCtr = refr,
onRefresh: (refr) => controller.loadData(),
onLoading: (refr) => controller.loadData(isRefresh: false),
child: () {
if (controller.isLoading) return LoadingCenterWidget();
if (controller.isEmptyData) return CErrorWidget();
final list = controller.dataList!;
return ListView.builder(
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: CommunityPostWidget(
videoModel: list[index],
isMyPublish: true,
showCheck: inEdit,
isChecked: logic.checkedList.contains(list[index]),
onItemCheck: (videoModel, isChecked) {
if (isChecked) {
logic.addChecked(videoModel);
} else {
logic.removeChecked(videoModel);
}
},
),
);
},
);
}(),
);
},
);
}
}