ar_tourism_flutter_unity/lib/pages/mine/drafts.dart
2025-05-14 17:04:13 +08:00

283 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../../../components/appbar.dart';
import '../../apis/app.dart';
import '../../components/CustomAlertDialog.dart';
import '../../components/emptyState.dart';
import '../../components/cached_image.dart';
class DraftsPage extends StatefulWidget {
const DraftsPage({super.key});
@override
State<DraftsPage> createState() => _DraftsPageState();
}
class _DraftsPageState extends State<DraftsPage> {
List drafts = [];
bool isLoading = false;
int currentPage = 1;
int totalCount = 0;
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
getDraftsList();
_scrollController.addListener(_onScroll);
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _onScroll() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_loadMore();
}
}
Future<void> _loadMore() async {
if (!isLoading && drafts.length < totalCount) {
await getDraftsList(page: currentPage + 1);
}
}
Future<void> getDraftsList({int page = 1}) async {
print('获取草稿箱数据: $page');
if (isLoading) return;
setState(() => isLoading = true);
try {
var result = await userApi.getDrafts(
page: page,
pageSize: 10,
);
if (result['code'] == 200) {
print('草稿箱数据: $result');
setState(() {
if (page == 1) {
drafts = List.from(result['rows']);
} else {
drafts.addAll(result['rows']);
}
totalCount = result['total'];
currentPage = page;
isLoading = false;
});
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('获取草稿箱数据失败: ${e.toString()}')),
);
}
setState(() => isLoading = false);
}
}
Future<void> _deleteDraft(int workId) async {
try {
var result = await userApi.deleteDraft(workId);
if (result['code'] == 200) {
// 重新获取第一页数据
currentPage = 1;
await getDraftsList(page: 1);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('删除失败: ${e.toString()}')),
);
}
}
}
void _showDeleteConfirmationDialog(int workId) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CustomAlertDialog(
title: '确定删除此作品?',
content: '',
onConfirm: () async {
Navigator.of(context).pop(); // 关闭弹窗
await _deleteDraft(workId);
},
confirmText: '确定',
cancelText: '取消',
);
},
);
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: true,
onPopInvoked: (didPop) {
if (!didPop) {
Navigator.pop(context);
}
},
child: Scaffold(
appBar: CustomAppBar(
title: '草稿箱',
onBackPressed: () {
Navigator.pop(context);
},
),
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('images/pwd_bg.png'),
fit: BoxFit.cover,
),
),
child: RefreshIndicator(
onRefresh: () => getDraftsList(page: 1),
child: drafts.isEmpty && !isLoading
? const EmptyState(message: '暂无草稿')
: ListView(
controller: _scrollController,
children: [
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 0,
crossAxisSpacing: 0,
childAspectRatio: 166 / 219,
),
itemCount: drafts.length,
itemBuilder: (context, index) {
final draft = drafts[index];
return GestureDetector(
onTap: () {
print("草稿箱点击详情draft ${draft}");
Navigator.pushNamed(
context,
'/workEdit',
arguments: draft,
);
},
child: Container(
padding: const EdgeInsets.all(5),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Stack(
fit: StackFit.expand,
children: [
CachedImage(
imageUrl: draft['workAddress'] ?? '',
width: double.infinity,
height: 219,
fit: BoxFit.cover,
errorWidget: (context, url, error) => Container(
color: const Color(0xFF2C2C2C),
child: const Center(
child: Icon(
Icons.error,
color: Colors.white54,
),
),
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black.withOpacity(0.7),
],
stops: const [0.0, 1.0],
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
draft['workName'] ?? '未命名',
style: const TextStyle(
fontSize: 16,
color: Colors.white,
decoration: TextDecoration.none,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
GestureDetector(
child: Image.asset(
'images/del.png',
width: 16,
height: 16,
fit: BoxFit.contain,
color: Colors.white,
),
onTap: () {
_showDeleteConfirmationDialog(draft['workId']);
},
),
],
),
),
),
),
],
),
),
],
),
),
);
},
),
if (drafts.isNotEmpty)
Container(
padding: const EdgeInsets.symmetric(vertical: 16),
alignment: Alignment.center,
child: drafts.length < totalCount
? const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2.0,
color: Colors.white,
),
)
: const Text(
'已经到底啦',
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
),
],
),
),
),
),
);
}
}