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

584 lines
22 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../apis/app.dart';
import '../../components/CustomAlertDialog.dart';
import '../../components/appbar.dart';
import '../../providers/auth_provider.dart';
class InfoDetailPage extends StatefulWidget {
final Map<String, dynamic> arguments;
const InfoDetailPage({
super.key,
required this.arguments,
});
@override
State<InfoDetailPage> createState() => _InfoDetailPageState();
}
class _InfoDetailPageState extends State<InfoDetailPage> with WidgetsBindingObserver {
// final TextEditingController _commentController = TextEditingController();
bool _liked = false;
int _likesCount = 0;
bool _isFollowed = false;
bool _isOwnWork = false; // 添加标记是否为自己的作品
Map<String, dynamic>? workDetail;
bool isLoading = true; // 添加加载状态
String? error; // 添加错误状态
@override
void initState() {
super.initState();
print("InfoDetail初始化参数: ${widget.arguments}");
WidgetsBinding.instance.addObserver(this);
print('Initial like status: ${widget.arguments['isLiked']}');
_liked = widget.arguments['isLiked'].toString() == "1";
print('_liked value: $_liked');
_likesCount = widget.arguments['likeCount'];
_fetchWorkDetail();
}
@override
void dispose() {
final returnData = {
'workId': widget.arguments['workId'],
'isLiked': _liked ? "1" : "0",
'likeCount': _likesCount,
'isFollowed': _isFollowed,
'userId': workDetail?['userId'],
};
print("InfoDetail返回数据: $returnData");
if (Navigator.canPop(context)) {
Navigator.pop(context, returnData);
}
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// 页面重新获得焦点时刷新数据
_refreshData();
}
}
// 添加刷新方法
Future<void> _refreshData() async {
if (mounted) {
await _fetchWorkDetail();
}
}
Future<void> _fetchWorkDetail() async {
try {
setState(() {
isLoading = true;
error = null;
});
// 获取当前登录用户的ID
final authProvider = Provider.of<AuthProvider>(context, listen: false);
final currentUserId = authProvider.userId;
print("当前登录用户ID: $currentUserId");
var result = await userApi.getMyPublishDetail(widget.arguments['workId']);
// print("更多他人发布详情页面result---------------: $result");
if (result['code'] == 200) {
setState(() {
workDetail = result['data'];
print("更多他人发布详情页面workDetail---------------: ${workDetail?['userId']}");
workDetail?['isAddLike'] = _liked ? "1" : "0";
workDetail?['receiveRockets'] = _likesCount;
_isFollowed = workDetail?['isFollow'] == "1";
// 判断是否为自己的作品,确保类型一致后再比较
print("当前用户ID类型: ${currentUserId.runtimeType}, 值: $currentUserId");
print("作品用户ID类型: ${workDetail?['userId'].runtimeType}, 值: ${workDetail?['userId']}");
_isOwnWork = currentUserId.toString() == workDetail?['userId'].toString();
print("是否为自己的作品: $_isOwnWork, 比较结果: ${currentUserId.toString() == workDetail?['userId'].toString()}");
isLoading = false;
});
} else {
setState(() {
error = result['msg'] ?? '获取数据失败';
isLoading = false;
});
}
} catch (e) {
setState(() {
error = '网络请求失败';
isLoading = false;
});
}
}
// 当用户点击关注按钮时
Future<void> _toggleFollow() async {
if (workDetail?['userId'] == null) return;
try {
final previousState = _isFollowed;
setState(() {
_isFollowed = !_isFollowed;
workDetail!['isFollow'] = _isFollowed ? "1" : "0";
});
final result = _isFollowed
? await userApi.addFollow(workDetail!['userId'])
: await userApi.cancelFollow(workDetail!['userId']);
if (result['code'] != 200) {
setState(() {
_isFollowed = previousState;
workDetail!['isFollow'] = previousState ? "1" : "0";
});
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(result['msg'] ?? '操作失败')),
);
}
} catch (e) {
setState(() {
_isFollowed = !_isFollowed;
workDetail!['isFollow'] = _isFollowed ? "1" : "0";
});
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('网络请求失败')),
);
}
}
// 当用户点击头像进入OtherMinePage时
void _navigateToOtherMine() async {
if (workDetail == null) return;
final result = await Navigator.pushNamed(
context,
'/otherMine',
arguments: {
...workDetail!,
'isFollow': _isFollowed ? "1" : "0", // 使用当前组件的关注状态
},
);
// 处理从OtherMinePage返回的结果
if (result != null && result is Map<String, dynamic>) {
setState(() {
_isFollowed = result['isFollowed'];
workDetail!['isFollow'] = _isFollowed ? "1" : "0";
});
}
}
// 当用户点击头像时的处理逻辑
void _handleAvatarTap() {
if (_isOwnWork) {
// 如果是自己的作品使用pushNamed跳转到个人首页
Navigator.pushNamed(
context,
'/tabs',
arguments: {'initialIndex': 4},
);
} else {
// 如果是他人的作品跳转到otherMine页面
_navigateToOtherMine();
}
}
// 格式化展示信息
String _formatSourceDisplay() {
if (workDetail == null || workDetail!['sourceList'] == null) {
return "暂无展示信息";
}
List<dynamic> sourceList = workDetail!['sourceList'];
if (sourceList.isEmpty) {
return "暂无展示信息";
}
// 按照城市和景区分组
Map<String, List<dynamic>> groupedSources = {};
for (var source in sourceList) {
// 创建基础位置键(城市+景区不包含part
String baseLocation = "${source['city']}${source['scenic']}";
if (!groupedSources.containsKey(baseLocation)) {
groupedSources[baseLocation] = [];
}
groupedSources[baseLocation]!.add(source);
}
// 格式化每个分组的显示文本
List<String> displayTexts = groupedSources.entries.map((entry) {
var sources = entry.value;
// 获取第一个源的基本信息
var firstSource = sources.first;
String baseInfo = "${firstSource['city']}${firstSource['scenic']}";
// 收集所有完整坐标包含part
List<String> coordinates =
sources.map<String>((s) => "${s['part']}${s['coordinate']}").toList();
// 获取剩余天数(假设剩余天数相同)
int rDays = firstSource['rDays'];
// 组合最终显示文本
return "$baseInfo${coordinates.join('')}展示中,剩余$rDays天";
}).toList();
// 用分号连接不同景区的信息
return displayTexts.join('; ');
}
@override
Widget build(BuildContext context) {
// final workItem = workDetail?.isNotEmpty == true ? workDetail![0] : null;
return Scaffold(
body: Container(
color: const Color(0xFF0C0C16),
child: Column(
children: [
Container(
padding: EdgeInsets.only(
// 添加状态栏高度的 padding
top: MediaQuery.of(context).padding.top,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Image.asset(
'images/arraw.png',
width: 11,
height: 22,
fit: BoxFit.cover,
),
onPressed: () {
// 返回上一页
Navigator.pop(context);
},
),
// IconButton(
// icon: Image.asset(
// 'images/share.png',
// width: 19,
// height: 19,
// fit: BoxFit.cover,
// ),
// onPressed: () {
// // 分享操作
// },
// ),
]),
),
Expanded(
child: ListView(
padding: EdgeInsets.zero,
children: [
Stack(
children: [
Image.network(
workDetail?['workAddress'] ?? '',
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.55,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.55,
color: Colors.grey[900],
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.broken_image,
color: Colors.white54,
size: 48,
),
SizedBox(height: 8),
Text(
'图片加载失败',
style: TextStyle(
color: Colors.white54,
fontSize: 14,
),
),
],
),
),
);
},
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 80,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black.withOpacity(0.8),
],
),
),
),
),
Positioned(
bottom: 5,
left: 16,
child: Text(
workDetail?['workName'] ?? '',
style: const TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold),
))
],
),
Container(
padding: const EdgeInsets.all(20),
// color: Colors.grey[200],
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: _handleAvatarTap,
child: Row(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color(0xFF2C2C2C),
image: workDetail?['avatar'] != null &&
workDetail!['avatar'].toString().isNotEmpty
? DecorationImage(
image: NetworkImage(workDetail!['avatar']),
fit: BoxFit.cover,
)
: null,
),
child: workDetail?['avatar'] == null ||
workDetail!['avatar'].toString().isEmpty
? const Center(
child: Icon(
Icons.person,
color: Colors.white54,
size: 30,
),
)
: null,
),
const SizedBox(width: 8),
Text(
workDetail?['nickName'] ?? '',
style: const TextStyle(
fontSize: 20,
color: Color.fromRGBO(255, 255, 255, 0.8),
),
),
],
),
),
// 只有不是自己的作品时才显示关注按钮
if (!_isOwnWork)
TextButton(
onPressed: _toggleFollow,
style: ButtonStyle(
side: MaterialStateProperty.all(
BorderSide(
color: _isFollowed
? Colors.grey
: const Color(0xffF42845),
width: 0.67,
),
),
backgroundColor: MaterialStateProperty.all(
_isFollowed
? Colors.transparent
: const Color(0xffF42845),
),
padding: MaterialStateProperty.all(EdgeInsets.zero),
minimumSize: MaterialStateProperty.all(const Size(65, 25)),
maximumSize: MaterialStateProperty.all(const Size(65, 25)),
fixedSize: MaterialStateProperty.all(const Size(65, 25)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: Text(
_isFollowed ? '已关注' : '关注',
style: TextStyle(
color: _isFollowed ? Colors.grey : Colors.white,
fontSize: 12,
),
),
),
],
),
const SizedBox(height: 10),
Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.3, // 设置最大高度
),
child: SingleChildScrollView(
child: Text(
workDetail?['detail'] ?? '',
style: const TextStyle(
fontSize: 16,
color: Color.fromRGBO(255, 255, 255, 0.8),
),
),
),
),
const SizedBox(
height: 10,
),
Text(
workDetail?['createTime']
?.toString()
.substring(0, 10) ??
'',
style: const TextStyle(
fontSize: 10, color: Color(0xffD6D7DC))),
],
),
),
],
),
),
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.white.withOpacity(0.3)),
),
),
child: Row(
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
physics: const BouncingScrollPhysics(), // 添加弹性滚动效果,提高用户体验
child: Text(
_formatSourceDisplay(),
// 移除 overflow: TextOverflow.ellipsis, 允许文本完整显示
style: const TextStyle(
color: Color(0xff78E7A4),
fontSize: 10,
),
),
),
),
// Expanded(
// child: Text(
// _formatSourceDisplay(),
// // overflow: TextOverflow.ellipsis,
// style: const TextStyle(
// color: Color(0xff78E7A4),
// fontSize: 10,
// ),
// ),
// ),
const SizedBox(width: 8),
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
constraints: const BoxConstraints(
minWidth: 36,
minHeight: 36,
),
padding: EdgeInsets.zero,
icon: Image.asset(
'images/upvote.png',
width: 21,
height: 20,
fit: BoxFit.contain,
color: _liked
? const Color(0xffEE7371)
: const Color(0xffC1C1C1),
),
onPressed: () async {
try {
var result;
if (_liked) {
// 如果已点赞,则取消点赞
result = await userApi.getCancelLikeWork(
widget.arguments['workId']);
} else {
// 如果未点赞,则添加点赞
result = await userApi
.getLikeWork(widget.arguments['workId']);
}
if (result['code'] == 200) {
setState(() {
_liked = !_liked;
_likesCount += _liked ? 1 : -1;
if (workDetail != null) {
workDetail!['isAddLike'] = _liked ? "1" : "0";
workDetail!['receiveRockets'] = _likesCount;
}
});
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(result['msg'] ?? '操作失败')),
);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('网络请求失败')),
);
}
},
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.all(5)),
minimumSize:
MaterialStateProperty.all<Size>(const Size(0, 0)),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
iconSize: 30,
),
const SizedBox(width: 4),
Text(
_likesCount.toString(),
style: TextStyle(
color: _liked ? const Color(0xffEE7371) : const Color(0xffC1C1C1),
fontSize: 14,
),
),
],
),
],
),
),
],
),
),
);
}
}