初始化
This commit is contained in:
@@ -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);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user