Commit 99b94d6c8c09e2acd87603a1e61ee770cc607bbf

Authored by 吴启风
1 parent 09fb1af9

feat:首页增加信息弹窗

lib/common/request/api_response/api_response_entity.dart
1 1 import 'dart:convert';
2 2  
3   -import 'api_response_entity.g.dart';
  3 +import 'package:wow_english/common/request/api_response/api_response_entity.g.dart';
  4 +
4 5  
5 6 class ApiResponse<T> {
6 7 int? code;
... ...
lib/common/request/dao/system_dao.dart
  1 +import 'package:wow_english/models/popup_entity.dart';
  2 +
1 3 import '../../../models/app_config_entity.dart';
2 4 import '../../../models/app_version_entity.dart';
3 5 import '../request_client.dart';
... ... @@ -13,4 +15,9 @@ class SystemDao {
13 15 static Future<AppVersionEntity?> getVersionInfo() async {
14 16 return await requestClient.get(Apis.appVersion);
15 17 }
  18 +
  19 + // 获取弹窗信息
  20 + static Future<PopupEntity?> getPopupInfo() async {
  21 + return await requestClient.get(Apis.homePopup);
  22 + }
16 23 }
... ...
lib/generated/json/base/json_convert_content.dart
... ... @@ -14,6 +14,7 @@ import &#39;package:wow_english/models/course_section_entity.dart&#39;;
14 14 import 'package:wow_english/models/course_unit_entity.dart';
15 15 import 'package:wow_english/models/follow_read_entity.dart';
16 16 import 'package:wow_english/models/listen_entity.dart';
  17 +import 'package:wow_english/models/popup_entity.dart';
17 18 import 'package:wow_english/models/product_entity.dart';
18 19 import 'package:wow_english/models/read_content_entity.dart';
19 20 import 'package:wow_english/models/singsound_result_detail_entity.dart';
... ... @@ -225,6 +226,10 @@ class JsonConvert {
225 226 return data.map<ListenEntity>((Map<String, dynamic> e) =>
226 227 ListenEntity.fromJson(e)).toList() as M;
227 228 }
  229 + if (<PopupEntity>[] is M) {
  230 + return data.map<PopupEntity>((Map<String, dynamic> e) =>
  231 + PopupEntity.fromJson(e)).toList() as M;
  232 + }
228 233 if (<ProductEntity>[] is M) {
229 234 return data.map<ProductEntity>((Map<String, dynamic> e) =>
230 235 ProductEntity.fromJson(e)).toList() as M;
... ... @@ -281,6 +286,7 @@ class JsonConvertClassCollection {
281 286 (CourseUnitDetail).toString(): CourseUnitDetail.fromJson,
282 287 (FollowReadEntity).toString(): FollowReadEntity.fromJson,
283 288 (ListenEntity).toString(): ListenEntity.fromJson,
  289 + (PopupEntity).toString(): PopupEntity.fromJson,
284 290 (ProductEntity).toString(): ProductEntity.fromJson,
285 291 (ReadContentEntity).toString(): ReadContentEntity.fromJson,
286 292 (SingsoundResultDetailEntity).toString(): SingsoundResultDetailEntity
... ...
lib/generated/json/popup_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/popup_entity.dart';
  3 +
  4 +PopupEntity $PopupEntityFromJson(Map<String, dynamic> json) {
  5 + final PopupEntity popupEntity = PopupEntity();
  6 + final String? actionType = jsonConvert.convert<String>(json['actionType']);
  7 + if (actionType != null) {
  8 + popupEntity.actionType = actionType;
  9 + }
  10 + final String? actionValue = jsonConvert.convert<String>(json['actionValue']);
  11 + if (actionValue != null) {
  12 + popupEntity.actionValue = actionValue;
  13 + }
  14 + final int? dayNum = jsonConvert.convert<int>(json['dayNum']);
  15 + if (dayNum != null) {
  16 + popupEntity.dayNum = dayNum;
  17 + }
  18 + final String? id = jsonConvert.convert<String>(json['id']);
  19 + if (id != null) {
  20 + popupEntity.id = id;
  21 + }
  22 + final String? imageId = jsonConvert.convert<String>(json['imageId']);
  23 + if (imageId != null) {
  24 + popupEntity.imageId = imageId;
  25 + }
  26 + final int? status = jsonConvert.convert<int>(json['status']);
  27 + if (status != null) {
  28 + popupEntity.status = status;
  29 + }
  30 + return popupEntity;
  31 +}
  32 +
  33 +Map<String, dynamic> $PopupEntityToJson(PopupEntity entity) {
  34 + final Map<String, dynamic> data = <String, dynamic>{};
  35 + data['actionType'] = entity.actionType;
  36 + data['actionValue'] = entity.actionValue;
  37 + data['dayNum'] = entity.dayNum;
  38 + data['id'] = entity.id;
  39 + data['imageId'] = entity.imageId;
  40 + data['status'] = entity.status;
  41 + return data;
  42 +}
  43 +
  44 +extension PopupEntityExtension on PopupEntity {
  45 + PopupEntity copyWith({
  46 + String? actionType,
  47 + String? actionValue,
  48 + int? dayNum,
  49 + String? id,
  50 + String? imageId,
  51 + int? status,
  52 + }) {
  53 + return PopupEntity()
  54 + ..actionType = actionType ?? this.actionType
  55 + ..actionValue = actionValue ?? this.actionValue
  56 + ..dayNum = dayNum ?? this.dayNum
  57 + ..id = id ?? this.id
  58 + ..imageId = imageId ?? this.imageId
  59 + ..status = status ?? this.status;
  60 + }
  61 +}
0 62 \ No newline at end of file
... ...
lib/models/popup_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/popup_entity.g.dart';
  3 +import 'dart:convert';
  4 +
  5 +@JsonSerializable()
  6 +class PopupEntity {
  7 + late String actionType;
  8 + late String actionValue;
  9 + late int dayNum;
  10 + late String id;
  11 + late String imageId;
  12 + late int status;
  13 +
  14 + PopupEntity();
  15 +
  16 + factory PopupEntity.fromJson(Map<String, dynamic> json) => $PopupEntityFromJson(json);
  17 +
  18 + Map<String, dynamic> toJson() => $PopupEntityToJson(this);
  19 +
  20 + @override
  21 + String toString() {
  22 + return jsonEncode(this);
  23 + }
  24 +}
0 25 \ No newline at end of file
... ...
lib/pages/home/PopupType.dart 0 → 100644
  1 +enum PopupType {
  2 + ///无交互
  3 + none,
  4 +
  5 + ///网页
  6 + h5,
  7 +
  8 + ///协议。如果是协议的话 获得的就是一个协议链接 jump://home/buy?courseMealId=1(暂时没有使用场景)
  9 + protocol
  10 +}
0 11 \ No newline at end of file
... ...
lib/pages/home/bloc.dart
... ... @@ -2,6 +2,7 @@ import &#39;dart:async&#39;;
2 2  
3 3 import 'package:bloc/bloc.dart';
4 4 import 'package:wow_english/common/core/user_util.dart';
  5 +import 'package:wow_english/models/popup_entity.dart';
5 6 import 'package:wow_english/utils/audio_player_util.dart';
6 7  
7 8 import '../../common/core/app_config_helper.dart';
... ... @@ -24,6 +25,7 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
24 25 AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch);
25 26 }
26 27 await _checkUpdate(emit);
  28 + await _getPopupInfo(emit);
27 29 }
28 30  
29 31 void _exchangeSuccess(
... ... @@ -51,4 +53,14 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
51 53 appVersionEntity));
52 54 }
53 55 }
  56 +
  57 + Future<void> _getPopupInfo(Emitter<HomeState> emit) async {
  58 + PopupEntity? popupEntity = await SystemDao.getPopupInfo();
  59 + Log.d(
  60 + "HomeBloc _getPopupInfo _getPopupInfo: $popupEntity");
  61 + if (popupEntity == null) {
  62 + return;
  63 + }
  64 + emit(PopupDialogState(popupEntity));
  65 + }
54 66 }
... ...
lib/pages/home/state.dart
1 1 import 'package:wow_english/models/app_version_entity.dart';
  2 +import 'package:wow_english/models/popup_entity.dart';
2 3  
3 4 class HomeState {
4 5 HomeState init() {
... ... @@ -18,3 +19,10 @@ class UpdateDialogState extends HomeState {
18 19  
19 20 UpdateDialogState(this.forceUpdate, this.appVersionEntity);
20 21 }
  22 +
  23 +class PopupDialogState extends HomeState {
  24 +
  25 + final PopupEntity popupEntity;
  26 +
  27 + PopupDialogState(this.popupEntity);
  28 +}
... ...
lib/pages/home/view.dart
1 1 import 'dart:io';
2 2  
  3 +import 'package:flutter/cupertino.dart';
3 4 import 'package:flutter/material.dart';
4 5 import 'package:flutter/services.dart';
5 6 import 'package:flutter_app_update/azhon_app_update.dart';
... ... @@ -11,6 +12,8 @@ import &#39;package:wow_english/common/core/app_config_helper.dart&#39;;
11 12 import 'package:wow_english/common/core/app_consts.dart';
12 13 import 'package:wow_english/common/extension/string_extension.dart';
13 14 import 'package:wow_english/models/app_version_entity.dart';
  15 +import 'package:wow_english/models/popup_entity.dart';
  16 +import 'package:wow_english/pages/home/PopupType.dart';
14 17 import 'package:wow_english/pages/home/state.dart';
15 18 import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart';
16 19 import 'package:wow_english/pages/home/widgets/ShakeImage.dart';
... ... @@ -20,6 +23,7 @@ import &#39;package:wow_english/utils/audio_player_util.dart&#39;;
20 23 import '../../common/core/user_util.dart';
21 24 import '../../common/dialogs/show_dialog.dart';
22 25 import '../../common/utils/click_with_music_controller.dart';
  26 +import '../../common/widgets/ow_image_widget.dart';
23 27 import 'bloc.dart';
24 28 import 'event.dart';
25 29 import 'package:flutter_screenutil/flutter_screenutil.dart';
... ... @@ -49,6 +53,8 @@ class _HomePageView extends StatelessWidget {
49 53 if (state is UpdateDialogState) {
50 54 _showUpdateDialog(
51 55 context, state.forceUpdate, state.appVersionEntity);
  56 + } else if (state is PopupDialogState) {
  57 + _showPopupDialog(context, state.popupEntity);
52 58 }
53 59 },
54 60 ),
... ... @@ -314,4 +320,54 @@ class _HomePageView extends StatelessWidget {
314 320 throw 'Could not launch $url';
315 321 }
316 322 }
  323 +
  324 + ///popup对话框
  325 + void _showPopupDialog(BuildContext context, PopupEntity popupEntity) {
  326 + if (popupEntity.imageId.isEmpty) {
  327 + return;
  328 + }
  329 + showDialog(
  330 + context: context,
  331 + barrierDismissible: false,
  332 + builder: (BuildContext context) {
  333 + return Dialog(
  334 + backgroundColor: Colors.transparent,
  335 + child: Stack(
  336 + alignment: Alignment.topRight,
  337 + children: [
  338 + // 图片内容区域
  339 + ClipRRect(
  340 + borderRadius: BorderRadius.circular(16), // 可选:圆角
  341 + child: GestureDetector(
  342 + onTap: () {
  343 + if (popupEntity.actionType == PopupType.h5.name &&
  344 + popupEntity.actionValue.isNotEmpty) {
  345 + Navigator.of(context).pop();
  346 + Navigator.of(context).pushNamed(AppRouteName.webView,
  347 + arguments: {'urlStr': popupEntity.actionValue});
  348 + }
  349 + },
  350 + child: OwImageWidget(
  351 + height: MediaQuery.of(context).size.height * 0.8,
  352 + name: popupEntity.imageId,
  353 + fit: BoxFit.fitHeight),
  354 + ),
  355 + ),
  356 + Positioned(
  357 + top: 0,
  358 + right: 0,
  359 + child: IconButton(
  360 + icon: const Icon(Icons.close, color: Colors.white, opticalSize: 2),
  361 + onPressed: () {
  362 + Navigator.of(context).pop();
  363 + },
  364 + ),
  365 + ),
  366 + ],
  367 + // 图片宽度和高度是屏幕高度的80%,右上角有一个关闭按钮,点击关闭按钮关闭对话框,图片水平居中,高度在按钮垂直方向下方
  368 + ),
  369 + );
  370 + },
  371 + );
  372 + }
317 373 }
... ...
lib/route/route.dart
... ... @@ -217,7 +217,7 @@ class AppRouter {
217 217 case AppRouteName.webView:
218 218 final urlStr = (settings.arguments as Map)['urlStr'] as String;
219 219 final webViewTitle =
220   - (settings.arguments as Map)['webViewTitle'] as String;
  220 + (settings.arguments as Map)['webViewTitle'] as String?;
221 221 return CupertinoPageRoute(
222 222 builder: (_) => WowWebViewPage(
223 223 urlStr: urlStr,
... ...