diff --git a/lib/common/request/api_response/api_response_entity.dart b/lib/common/request/api_response/api_response_entity.dart index ec66435..3a66241 100644 --- a/lib/common/request/api_response/api_response_entity.dart +++ b/lib/common/request/api_response/api_response_entity.dart @@ -1,6 +1,7 @@ import 'dart:convert'; -import 'api_response_entity.g.dart'; +import 'package:wow_english/common/request/api_response/api_response_entity.g.dart'; + class ApiResponse { int? code; diff --git a/lib/common/request/dao/system_dao.dart b/lib/common/request/dao/system_dao.dart index 78c04c5..15bfe41 100644 --- a/lib/common/request/dao/system_dao.dart +++ b/lib/common/request/dao/system_dao.dart @@ -1,3 +1,5 @@ +import 'package:wow_english/models/popup_entity.dart'; + import '../../../models/app_config_entity.dart'; import '../../../models/app_version_entity.dart'; import '../request_client.dart'; @@ -13,4 +15,9 @@ class SystemDao { static Future getVersionInfo() async { return await requestClient.get(Apis.appVersion); } + + // 获取弹窗信息 + static Future getPopupInfo() async { + return await requestClient.get(Apis.homePopup); + } } diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index b60f603..87e4f84 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -14,6 +14,7 @@ import 'package:wow_english/models/course_section_entity.dart'; import 'package:wow_english/models/course_unit_entity.dart'; import 'package:wow_english/models/follow_read_entity.dart'; import 'package:wow_english/models/listen_entity.dart'; +import 'package:wow_english/models/popup_entity.dart'; import 'package:wow_english/models/product_entity.dart'; import 'package:wow_english/models/read_content_entity.dart'; import 'package:wow_english/models/singsound_result_detail_entity.dart'; @@ -225,6 +226,10 @@ class JsonConvert { return data.map((Map e) => ListenEntity.fromJson(e)).toList() as M; } + if ([] is M) { + return data.map((Map e) => + PopupEntity.fromJson(e)).toList() as M; + } if ([] is M) { return data.map((Map e) => ProductEntity.fromJson(e)).toList() as M; @@ -281,6 +286,7 @@ class JsonConvertClassCollection { (CourseUnitDetail).toString(): CourseUnitDetail.fromJson, (FollowReadEntity).toString(): FollowReadEntity.fromJson, (ListenEntity).toString(): ListenEntity.fromJson, + (PopupEntity).toString(): PopupEntity.fromJson, (ProductEntity).toString(): ProductEntity.fromJson, (ReadContentEntity).toString(): ReadContentEntity.fromJson, (SingsoundResultDetailEntity).toString(): SingsoundResultDetailEntity diff --git a/lib/generated/json/popup_entity.g.dart b/lib/generated/json/popup_entity.g.dart new file mode 100644 index 0000000..7856324 --- /dev/null +++ b/lib/generated/json/popup_entity.g.dart @@ -0,0 +1,61 @@ +import 'package:wow_english/generated/json/base/json_convert_content.dart'; +import 'package:wow_english/models/popup_entity.dart'; + +PopupEntity $PopupEntityFromJson(Map json) { + final PopupEntity popupEntity = PopupEntity(); + final String? actionType = jsonConvert.convert(json['actionType']); + if (actionType != null) { + popupEntity.actionType = actionType; + } + final String? actionValue = jsonConvert.convert(json['actionValue']); + if (actionValue != null) { + popupEntity.actionValue = actionValue; + } + final int? dayNum = jsonConvert.convert(json['dayNum']); + if (dayNum != null) { + popupEntity.dayNum = dayNum; + } + final String? id = jsonConvert.convert(json['id']); + if (id != null) { + popupEntity.id = id; + } + final String? imageId = jsonConvert.convert(json['imageId']); + if (imageId != null) { + popupEntity.imageId = imageId; + } + final int? status = jsonConvert.convert(json['status']); + if (status != null) { + popupEntity.status = status; + } + return popupEntity; +} + +Map $PopupEntityToJson(PopupEntity entity) { + final Map data = {}; + data['actionType'] = entity.actionType; + data['actionValue'] = entity.actionValue; + data['dayNum'] = entity.dayNum; + data['id'] = entity.id; + data['imageId'] = entity.imageId; + data['status'] = entity.status; + return data; +} + +extension PopupEntityExtension on PopupEntity { + PopupEntity copyWith({ + String? actionType, + String? actionValue, + int? dayNum, + String? id, + String? imageId, + int? status, + }) { + return PopupEntity() + ..actionType = actionType ?? this.actionType + ..actionValue = actionValue ?? this.actionValue + ..dayNum = dayNum ?? this.dayNum + ..id = id ?? this.id + ..imageId = imageId ?? this.imageId + ..status = status ?? this.status; + } +} \ No newline at end of file diff --git a/lib/models/popup_entity.dart b/lib/models/popup_entity.dart new file mode 100644 index 0000000..4363048 --- /dev/null +++ b/lib/models/popup_entity.dart @@ -0,0 +1,24 @@ +import 'package:wow_english/generated/json/base/json_field.dart'; +import 'package:wow_english/generated/json/popup_entity.g.dart'; +import 'dart:convert'; + +@JsonSerializable() +class PopupEntity { + late String actionType; + late String actionValue; + late int dayNum; + late String id; + late String imageId; + late int status; + + PopupEntity(); + + factory PopupEntity.fromJson(Map json) => $PopupEntityFromJson(json); + + Map toJson() => $PopupEntityToJson(this); + + @override + String toString() { + return jsonEncode(this); + } +} \ No newline at end of file diff --git a/lib/pages/home/PopupType.dart b/lib/pages/home/PopupType.dart new file mode 100644 index 0000000..36394f9 --- /dev/null +++ b/lib/pages/home/PopupType.dart @@ -0,0 +1,10 @@ +enum PopupType { + ///无交互 + none, + + ///网页 + h5, + + ///协议。如果是协议的话 获得的就是一个协议链接 jump://home/buy?courseMealId=1(暂时没有使用场景) + protocol +} \ No newline at end of file diff --git a/lib/pages/home/bloc.dart b/lib/pages/home/bloc.dart index 048f624..9025d96 100644 --- a/lib/pages/home/bloc.dart +++ b/lib/pages/home/bloc.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:wow_english/common/core/user_util.dart'; +import 'package:wow_english/models/popup_entity.dart'; import 'package:wow_english/utils/audio_player_util.dart'; import '../../common/core/app_config_helper.dart'; @@ -24,6 +25,7 @@ class HomeBloc extends Bloc { AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch); } await _checkUpdate(emit); + await _getPopupInfo(emit); } void _exchangeSuccess( @@ -51,4 +53,14 @@ class HomeBloc extends Bloc { appVersionEntity)); } } + + Future _getPopupInfo(Emitter emit) async { + PopupEntity? popupEntity = await SystemDao.getPopupInfo(); + Log.d( + "HomeBloc _getPopupInfo _getPopupInfo: $popupEntity"); + if (popupEntity == null) { + return; + } + emit(PopupDialogState(popupEntity)); + } } diff --git a/lib/pages/home/state.dart b/lib/pages/home/state.dart index 45a8985..9a0eadf 100644 --- a/lib/pages/home/state.dart +++ b/lib/pages/home/state.dart @@ -1,4 +1,5 @@ import 'package:wow_english/models/app_version_entity.dart'; +import 'package:wow_english/models/popup_entity.dart'; class HomeState { HomeState init() { @@ -18,3 +19,10 @@ class UpdateDialogState extends HomeState { UpdateDialogState(this.forceUpdate, this.appVersionEntity); } + +class PopupDialogState extends HomeState { + + final PopupEntity popupEntity; + + PopupDialogState(this.popupEntity); +} diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index 22a3a15..1cb6ce6 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_app_update/azhon_app_update.dart'; @@ -11,6 +12,8 @@ import 'package:wow_english/common/core/app_config_helper.dart'; import 'package:wow_english/common/core/app_consts.dart'; import 'package:wow_english/common/extension/string_extension.dart'; import 'package:wow_english/models/app_version_entity.dart'; +import 'package:wow_english/models/popup_entity.dart'; +import 'package:wow_english/pages/home/PopupType.dart'; import 'package:wow_english/pages/home/state.dart'; import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart'; import 'package:wow_english/pages/home/widgets/ShakeImage.dart'; @@ -20,6 +23,7 @@ import 'package:wow_english/utils/audio_player_util.dart'; import '../../common/core/user_util.dart'; import '../../common/dialogs/show_dialog.dart'; import '../../common/utils/click_with_music_controller.dart'; +import '../../common/widgets/ow_image_widget.dart'; import 'bloc.dart'; import 'event.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -49,6 +53,8 @@ class _HomePageView extends StatelessWidget { if (state is UpdateDialogState) { _showUpdateDialog( context, state.forceUpdate, state.appVersionEntity); + } else if (state is PopupDialogState) { + _showPopupDialog(context, state.popupEntity); } }, ), @@ -314,4 +320,54 @@ class _HomePageView extends StatelessWidget { throw 'Could not launch $url'; } } + + ///popup对话框 + void _showPopupDialog(BuildContext context, PopupEntity popupEntity) { + if (popupEntity.imageId.isEmpty) { + return; + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return Dialog( + backgroundColor: Colors.transparent, + child: Stack( + alignment: Alignment.topRight, + children: [ + // 图片内容区域 + ClipRRect( + borderRadius: BorderRadius.circular(16), // 可选:圆角 + child: GestureDetector( + onTap: () { + if (popupEntity.actionType == PopupType.h5.name && + popupEntity.actionValue.isNotEmpty) { + Navigator.of(context).pop(); + Navigator.of(context).pushNamed(AppRouteName.webView, + arguments: {'urlStr': popupEntity.actionValue}); + } + }, + child: OwImageWidget( + height: MediaQuery.of(context).size.height * 0.8, + name: popupEntity.imageId, + fit: BoxFit.fitHeight), + ), + ), + Positioned( + top: 0, + right: 0, + child: IconButton( + icon: const Icon(Icons.close, color: Colors.white, opticalSize: 2), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + ], + // 图片宽度和高度是屏幕高度的80%,右上角有一个关闭按钮,点击关闭按钮关闭对话框,图片水平居中,高度在按钮垂直方向下方 + ), + ); + }, + ); + } } diff --git a/lib/route/route.dart b/lib/route/route.dart index 277184f..1e998f2 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -217,7 +217,7 @@ class AppRouter { case AppRouteName.webView: final urlStr = (settings.arguments as Map)['urlStr'] as String; final webViewTitle = - (settings.arguments as Map)['webViewTitle'] as String; + (settings.arguments as Map)['webViewTitle'] as String?; return CupertinoPageRoute( builder: (_) => WowWebViewPage( urlStr: urlStr,