| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- import 'dart:io';
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
- import 'package:news_app/constant/color_res.dart';
- import 'package:news_app/constant/config.dart';
- import 'package:news_app/util/time_util.dart';
- import '../../constant/size_res.dart';
- import '../../model/activity_model.dart';
- import '../../provider/activity_detail_provider.dart';
- import '../../util/device_util.dart';
- import '../../util/share_util.dart';
- import '../../widget/load_image.dart';
- import '../../widget/my_txt.dart';
- import '../../widget/right_action_widget.dart';
- class ActivityDetailPage extends ConsumerStatefulWidget {
- final String activityId;
- const ActivityDetailPage(this.activityId, {super.key});
- @override
- ConsumerState<ActivityDetailPage> createState() => _ActivityDetailPageState();
- }
- final activityDetailProvider =
- NotifierProvider<ActivityDetailProvider, ActivityModelRecord>(
- () => ActivityDetailProvider(),
- );
- String getRegisterStatus(String registerStatus) {
- switch (registerStatus) {
- case "0":
- return "未报名";
- case "1":
- return "已报名";
- case "2":
- return "审核通过";
- case "3":
- return "审核不通过";
- default:
- return "未报名";
- }
- }
- class _ActivityDetailPageState extends ConsumerState<ActivityDetailPage> {
- bool _isWeChatInstalled = false;
- @override
- void initState() {
- super.initState();
- ref
- .read(activityDetailProvider.notifier)
- .fetchActivityDetail(activityId: widget.activityId);
- _checkWeChatInstallation();
- }
- Future<void> _checkWeChatInstallation() async {
- if (Platform.isAndroid) {
- final installed = await isWeChatInstalledOnlyAndroid();
- setState(() => _isWeChatInstalled = installed);
- } else if (Platform.isIOS) {
- final installed = await fluwx.isWeChatInstalled;
- setState(() => _isWeChatInstalled = installed);
- }
- }
- @override
- void dispose() {
- _nameController.dispose();
- _phoneController.dispose();
- super.dispose();
- }
- final TextEditingController _nameController = TextEditingController();
- final TextEditingController _phoneController = TextEditingController();
- Future<void> shareAction(ActivityModelRecord data) async {
- showModalBottomSheet(
- context: context,
- builder:
- (context) => SafeArea(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- SizedBox(height: 10.h),
- Container(
- width: double.infinity,
- height: 80.h,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(10.r),
- topRight: Radius.circular(10.r),
- ),
- color: Colors.white,
- ),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- if (_isWeChatInstalled)
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareWeiXinUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_wxhy',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "微信好友",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- if (_isWeChatInstalled)
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareWeiXinPYUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_pyq',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "朋友圈",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_xtfx',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "系统分享",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- );
- }
- void _showRegisterDialog(WidgetRef ref) {
- showModalBottomSheet(
- backgroundColor: Colors.transparent,
- isScrollControlled: true, // 🔥 关键:允许内容超出默认高度
- context: context,
- builder: (BuildContext context) {
- return DraggableScrollableSheet(
- initialChildSize: 0.6,
- maxChildSize: 0.9,
- minChildSize: 0.4,
- expand: false,
- builder: (context, scrollController) {
- return ClipRRect(
- borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)),
- child: Container(
- padding: EdgeInsets.only(
- left: horizontalPadding,
- right: horizontalPadding,
- bottom: bottomBarHeight, // 🔥 关键:适配键盘高度
- ),
- color: Colors.white,
- child: SingleChildScrollView(
- controller: scrollController,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(height: 30.h),
- Center(
- child: myTxt(
- text: "活动报名",
- fontWeight: FontWeight.bold,
- fontSize: 18.sp,
- color: color333333,
- ),
- ),
- SizedBox(height: 30.h),
- Text.rich(
- TextSpan(
- text: "*",
- style: TextStyle(color: Colors.red),
- children: [
- TextSpan(
- text: "姓名",
- style: TextStyle(
- color: color333333,
- fontSize: 16.sp,
- ),
- ),
- ],
- ),
- ),
- SizedBox(height: 15.h),
- SizedBox(
- height: 50.h,
- child: TextField(
- controller: _nameController,
- textInputAction: TextInputAction.next,
- decoration: InputDecoration(
- contentPadding: EdgeInsets.only(
- bottom: 4.h,
- left: 10.w,
- ),
- hintText: "请输入姓名",
- hintStyle: TextStyle(
- color: color666666,
- fontSize: 16.sp,
- ),
- //无边框
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(8.r),
- borderSide: BorderSide.none,
- ),
- fillColor: colorF5F7FD,
- filled: true,
- ),
- ),
- ),
- SizedBox(height: 30.h),
- Text.rich(
- TextSpan(
- text: "*",
- style: TextStyle(color: Colors.red),
- children: [
- TextSpan(
- text: "手机号",
- style: TextStyle(
- color: color333333,
- fontSize: 16.sp,
- ),
- ),
- ],
- ),
- ),
- SizedBox(height: 15.h),
- SizedBox(
- height: 50.h,
- child: TextField(
- controller: _phoneController,
- keyboardType: TextInputType.phone,
- textInputAction: TextInputAction.done,
- decoration: InputDecoration(
- contentPadding: EdgeInsets.only(
- bottom: 4.h,
- left: 10.w,
- ),
- hintText: "请输入手机号",
- hintStyle: TextStyle(
- color: color666666,
- fontSize: 16.sp,
- ),
- //无边框
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(8.r),
- borderSide: BorderSide.none,
- ),
- fillColor: colorF5F7FD,
- filled: true,
- ),
- ),
- ),
- SizedBox(height: 30.h),
- GestureDetector(
- onTap: () {
- ref
- .watch(activityDetailProvider.notifier)
- .fetchRegisterActivity(
- activityId: widget.activityId,
- name: _nameController.text,
- phone: _phoneController.text,
- );
- },
- child: Container(
- margin: EdgeInsets.symmetric(vertical: 20.h),
- decoration: BoxDecoration(
- color: color5F59F7,
- borderRadius: BorderRadius.all(
- Radius.circular(20.r),
- ),
- ),
- height: 45.h,
- alignment: Alignment.center,
- child: myTxt(
- text: "提交",
- color: Colors.white,
- fontSize: 16.sp,
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- },
- );
- },
- );
- }
- @override
- Widget build(BuildContext context) {
- final detail = ref.watch(activityDetailProvider);
- return Scaffold(
- appBar: AppBar(
- // 移除阴影
- scrolledUnderElevation: 0,
- centerTitle: true,
- // 禁用滚动时的阴影变化
- title: myTxt(text: "活动详情", color: Colors.black, fontSize: 18.sp),
- leading: IconButton(
- icon: Icon(Icons.arrow_back_ios, color: Colors.black),
- onPressed: () {
- Navigator.pop(context);
- },
- ),
- actions: [
- Padding(
- padding: EdgeInsets.only(right: horizontalPadding),
- child: RightActionWidget(
- isLike: detail.isLiked ?? false,
- isFavorite: detail.isFavorite ?? false,
- tap: (value) {
- if (value == 0) {
- ref
- .read(activityDetailProvider.notifier)
- .fetchActivityLike(
- contentId: widget.activityId,
- current: detail.isLiked ?? false,
- );
- } else if (value == 1) {
- ref
- .read(activityDetailProvider.notifier)
- .fetchActivityFavorite(
- contentId: widget.activityId,
- current: detail.isFavorite ?? false,
- );
- } else if (value == 2) {
- // shareUrl(
- // title: detail.shareDesc ?? "",
- // url: detail.shareUrl ?? "",
- // );
- shareAction(detail);
- if (uuid.isNotEmpty) {
- ref
- .read(activityDetailProvider.notifier)
- .fetchActivityShare(activityId: widget.activityId);
- }
- }
- },
- ),
- ),
- ],
- ),
- body: Stack(
- children: [
- LoadImage(
- detail.image ?? 'bignone',
- width: double.infinity,
- height: 190.h,
- fit: BoxFit.fill,
- holderImg: 'bignone',
- ),
- SingleChildScrollView(
- child: Column(
- children: [
- SizedBox(height: 169.h),
- Container(
- padding: EdgeInsets.only(
- left: 14.w,
- right: 14.w,
- bottom: 26.h,
- ),
- decoration: BoxDecoration(
- color: Color(0xFFFFFFFF),
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(16),
- topRight: Radius.circular(16),
- ),
- ),
- child: Column(
- children: [
- SizedBox(height: 10.w),
- myTxt(
- text: detail.title ?? "金融赋能镇江高质量发展大会",
- color: Colors.black,
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- SizedBox(height: 10.w),
- Text(
- detail.summary ??
- "继今年全市“新春第一会”再次吹响“产业强市”号角后,在3月5日召开的全市金融系统工作会议上,“产业强市”再次成为高频词。",
- style: TextStyle(
- color: Color(0xFF333333),
- fontSize: 13,
- ),
- maxLines: 1000,
- ),
- SizedBox(height: 10.w),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Container(
- width: 10.w,
- height: 10.h,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- color: Color(0xFF4578FF),
- borderRadius: BorderRadius.all(
- Radius.circular(5),
- ),
- ),
- child: Container(
- width: 6.w,
- height: 6.h,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- color: Color(0xFFFFFFFF),
- borderRadius: BorderRadius.all(
- Radius.circular(3),
- ),
- ),
- ),
- ),
- SizedBox(width: 4),
- myTxt(
- text: "活动报名人数限额:${detail.registerLimit}",
- color: Color(0xFF333333),
- fontSize: 12,
- ),
- ],
- ),
- SizedBox(height: 10.w),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Container(
- width: 10.w,
- height: 10.h,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- color: Color(0xFF4578FF),
- borderRadius: BorderRadius.all(
- Radius.circular(5),
- ),
- ),
- child: Container(
- width: 6.w,
- height: 6.h,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- color: Color(0xFFFFFFFF),
- borderRadius: BorderRadius.all(
- Radius.circular(3),
- ),
- ),
- ),
- ),
- SizedBox(width: 4),
- myTxt(
- text:
- "活动报名时间:${TimeUtil.formatTime(detail.registerStartTime)} / ${TimeUtil.formatTime(detail.registerEndTime)}",
- color: Color(0xFF333333),
- fontSize: 12,
- ),
- ],
- ),
- SizedBox(height: 10.w),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Icon(
- Icons.alarm_outlined,
- color: Color(0xFF333333),
- size: 13,
- ),
- SizedBox(width: 4),
- myTxt(
- text:
- "时间:${TimeUtil.formatTime(detail.activityStartTime)} / ${TimeUtil.formatTime(detail.activityEndTime)}",
- color: Color(0xFF333333),
- fontSize: 12,
- ),
- ],
- ),
- SizedBox(height: 10.w),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Icon(
- Icons.location_on_outlined,
- color: Color(0xFF333333),
- size: 13,
- ),
- SizedBox(width: 4),
- myTxt(
- text: "地址:${detail.activityLocation}",
- color: Color(0xFF333333),
- fontSize: 12,
- ),
- ],
- ),
- SizedBox(height: 10.w),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Icon(
- Icons.people_alt_outlined,
- color: Color(0xFF333333),
- size: 13,
- ),
- SizedBox(width: 4),
- myTxt(
- text: "举办方:${detail.activityOrg}",
- color: Color(0xFF333333),
- fontSize: 12,
- ),
- ],
- ),
- SizedBox(height: 12.w),
- Container(
- color: Color(0xFFDCDFE2),
- height: 1,
- width: double.infinity,
- ),
- SizedBox(height: 12.h),
- HtmlWidget(detail.content ?? ""),
- ],
- ),
- ),
- ],
- ),
- ),
- if (detail.canRegister == true)
- Positioned(
- bottom: bottomBarHeight,
- left: horizontalPadding,
- right: horizontalPadding,
- child: ColoredBox(
- color: Colors.white,
- child: GestureDetector(
- onTap: () {
- if (detail.registerStatus == "0") {
- _showRegisterDialog(ref);
- }
- },
- child: Container(
- margin: EdgeInsets.symmetric(vertical: 20.h),
- decoration: BoxDecoration(
- color: color5F59F7,
- borderRadius: BorderRadius.all(Radius.circular(20.r)),
- ),
- height: 45.h,
- alignment: Alignment.center,
- child: myTxt(
- text: getRegisterStatus(detail.registerStatus ?? ""),
- color: Colors.white,
- fontSize: 16.sp,
- ),
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
- }
|