From 1fc7ba0ce0793b7ded0d10fa4c11eec18a12fd18 Mon Sep 17 00:00:00 2001
From: "1147192855@qq.com" <1147192855@qq.com>
Date: Tue, 2 Jul 2024 17:44:35 +0800
Subject: [PATCH] no message
---
.gitignore | 1 +
.../android/app/src/main/AndroidManifest.xml | 9 +
.../app/src/main/res/xml/file_paths.xml | 5 +
.../lib/common/api/retrofit_client.dart | 5 +
.../lib/common/config/request_config.dart | 2 +-
.../lib/common/job/app_version.dart | 53 +++++
.../lib/common/request/rest_dio.dart | 7 +-
.../common/utils/app_upgrade/DownloadApk.dart | 149 ++++++++++++
.../utils/app_upgrade/UpdateDialog.dart | 212 ++++++++++++++++++
.../utils/app_upgrade/UpgradePermission.dart | 142 ++++++++++++
.../app_upgrade/model/UpdateAppEvent.dart | 83 +++++++
.../utils/app_upgrade/upgradeLogic.dart | 63 ++++++
.../lib/common/utils/utils.dart | 150 ++++---------
making_school_asignment_app/lib/main.dart | 3 +
.../lib/page/global_widget/start_page.dart | 74 ++----
.../children/job_report/widget/top_count.dart | 16 +-
.../lib/page/login_page/login_view.dart | 24 +-
.../flutter/generated_plugin_registrant.cc | 4 +
.../linux/flutter/generated_plugins.cmake | 1 +
making_school_asignment_app/pubspec.yaml | 3 +
.../flutter/generated_plugin_registrant.cc | 6 +
.../windows/flutter/generated_plugins.cmake | 2 +
22 files changed, 843 insertions(+), 171 deletions(-)
create mode 100644 making_school_asignment_app/android/app/src/main/res/xml/file_paths.xml
create mode 100644 making_school_asignment_app/lib/common/job/app_version.dart
create mode 100644 making_school_asignment_app/lib/common/utils/app_upgrade/DownloadApk.dart
create mode 100644 making_school_asignment_app/lib/common/utils/app_upgrade/UpdateDialog.dart
create mode 100644 making_school_asignment_app/lib/common/utils/app_upgrade/UpgradePermission.dart
create mode 100644 making_school_asignment_app/lib/common/utils/app_upgrade/model/UpdateAppEvent.dart
create mode 100644 making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart
diff --git a/.gitignore b/.gitignore
index 2c3d1f0..ea828da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,3 +52,4 @@ making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view
making_school_asignment_app/lib/common/api/retrofit_client.g.dart
making_school_asignment_app/lib/page/home_page/children/read_over/read_over_view.g.dart
.vscode/settings.json
+.vscode/launch.json
diff --git a/making_school_asignment_app/android/app/src/main/AndroidManifest.xml b/making_school_asignment_app/android/app/src/main/AndroidManifest.xml
index c0d0fae..1ff64ab 100644
--- a/making_school_asignment_app/android/app/src/main/AndroidManifest.xml
+++ b/making_school_asignment_app/android/app/src/main/AndroidManifest.xml
@@ -31,6 +31,15 @@
+
+
+
+
+
diff --git a/making_school_asignment_app/android/app/src/main/res/xml/file_paths.xml b/making_school_asignment_app/android/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 0000000..b6480f6
--- /dev/null
+++ b/making_school_asignment_app/android/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/making_school_asignment_app/lib/common/api/retrofit_client.dart b/making_school_asignment_app/lib/common/api/retrofit_client.dart
index df8e36c..e803f76 100644
--- a/making_school_asignment_app/lib/common/api/retrofit_client.dart
+++ b/making_school_asignment_app/lib/common/api/retrofit_client.dart
@@ -1,4 +1,5 @@
import 'package:dio/dio.dart' hide Headers;
+import 'package:making_school_asignment_app/common/job/app_version.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_param.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_result.dart';
import 'package:making_school_asignment_app/common/job/marking_models/favor_param.dart';
@@ -137,4 +138,8 @@ abstract class RetrofitClient {
// OSS 上传key
@GET("/api/infra/Oss/GetPresignedUri")
Future getOssPresignedUri(@Query('key') String key);
+
+ // 获取APP 版本
+ @GET("/api/infra/AppVersion/Get")
+ Future getLastAppVersion(@Query('appName') String appName, @Query('ftuType') int ftuType); // ftuType 1安卓 2IOS
}
diff --git a/making_school_asignment_app/lib/common/config/request_config.dart b/making_school_asignment_app/lib/common/config/request_config.dart
index 3a04545..32cc6e6 100644
--- a/making_school_asignment_app/lib/common/config/request_config.dart
+++ b/making_school_asignment_app/lib/common/config/request_config.dart
@@ -11,7 +11,7 @@ import 'package:making_school_asignment_app/common/job/common/base_page.dart';
class RequestConfig {
static const _devBaseUrl = "http://192.168.2.119:1091"; // 开发
static const _proBaseUrl = "https://dpc-teacher-api.23544.com"; // 生产
- static const imgUrl = 'https://dpcjob.oss-cn-beijing.aliyuncs.com/';
+ static const imgUrl = 'https://dpc-job-oss.23544.com/';
static RequestConfig? _instance;
String baseUrl;
diff --git a/making_school_asignment_app/lib/common/job/app_version.dart b/making_school_asignment_app/lib/common/job/app_version.dart
new file mode 100644
index 0000000..aa8de30
--- /dev/null
+++ b/making_school_asignment_app/lib/common/job/app_version.dart
@@ -0,0 +1,53 @@
+import 'package:json_annotation/json_annotation.dart';
+
+import '../config/request_config.dart';
+
+part 'app_version.g.dart';
+
+@JsonSerializable()
+class AppVersion extends Object {
+ // @JsonKey(name: 'id')
+ // String id;
+
+ // @JsonKey(name: 'creatorId')
+ // int creatorId;
+
+ // @JsonKey(name: 'creatorName')
+ // String creatorName;
+
+ // @JsonKey(name: 'creationTime')
+ // String creationTime;
+
+ @JsonKey(name: 'appName')
+ String appName;
+
+ @JsonKey(name: 'version')
+ String version;
+
+ @JsonKey(name: 'ftuType')
+ int ftuType;
+
+ @JsonKey(name: 'downloadUrl')
+ String downloadUrl;
+
+ @JsonKey(name: 'description')
+ String? description;
+
+ AppVersion(
+ // this.id,
+ // this.creatorId,
+ // this.creatorName,
+ // this.creationTime,
+ this.appName,
+ this.version,
+ this.ftuType,
+ this.downloadUrl,
+ this.description,
+ ) {
+ downloadUrl = RequestConfig.imgUrl + downloadUrl;
+ }
+
+ factory AppVersion.fromJson(Map srcJson) => _$AppVersionFromJson(srcJson);
+
+ Map toJson() => _$AppVersionToJson(this);
+}
diff --git a/making_school_asignment_app/lib/common/request/rest_dio.dart b/making_school_asignment_app/lib/common/request/rest_dio.dart
index 49c3e8d..e94eba6 100644
--- a/making_school_asignment_app/lib/common/request/rest_dio.dart
+++ b/making_school_asignment_app/lib/common/request/rest_dio.dart
@@ -11,6 +11,7 @@ import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart';
import '../job/user_info_detail.dart';
+import '../utils/storage.dart';
class RequestTool {
static late Dio _dio;
@@ -168,7 +169,11 @@ class TheError extends Interceptor {
case 401:
message = '用户登录失效,请重新登录';
- Future.delayed(const Duration(seconds: 2), () => getx.Get.offAllNamed(Routes.login));
+ Future.delayed(const Duration(seconds: 2), () {
+ UserStore.to.erase();
+ StorageService.to.erase();
+ getx.Get.offAllNamed(Routes.login);
+ });
break;
case 404:
// message = '用户登录失效,请重新登录';
diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/DownloadApk.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/DownloadApk.dart
new file mode 100644
index 0000000..38dfe18
--- /dev/null
+++ b/making_school_asignment_app/lib/common/utils/app_upgrade/DownloadApk.dart
@@ -0,0 +1,149 @@
+/*
+ * @Descripttion: 下载APK
+ * @version: DownloadApk
+ * @Author: wy
+ * @Date: 2020-07-30 15:54:40
+ * @LastEditors: wangyang 1147192855@qq.com
+ * @LastEditTime: 2022-08-02 15:12:21
+ */
+import 'dart:io';
+
+import 'package:dio/dio.dart';
+import 'package:flutter/material.dart';
+import 'package:making_school_asignment_app/common/utils/utils.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:app_installer/app_installer.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import 'UpgradePermission.dart';
+import 'model/UpdateAppEvent.dart';
+import 'upgradeLogic.dart';
+
+class DownloadApk {
+ /// 下载安卓更新包
+ static Future _downloadAndroid(context, UpdateAppEvent event, UpgradeLogic logic) async {
+ /// 创建存储文件
+ Directory? storageDir = await getExternalStorageDirectory();
+ final storagePath = storageDir?.path ?? '/';
+ String version = event.version.replaceAll(".", "-");
+ File file = new File('$storagePath/${event.appName}v$version.apk');
+ if (await file.exists()) await file.delete();
+ if (!file.existsSync()) file.createSync();
+ try {
+ /// 发起下载请求
+ Response response = await Dio().get(
+ event.link,
+ onReceiveProgress: (num received, num total) {
+ showDownloadProgress(context, received, total, logic);
+ },
+ options: Options(
+ responseType: ResponseType.bytes,
+ followRedirects: false,
+ ),
+ );
+ file.writeAsBytesSync(response.data);
+ return file;
+ } catch (e) {
+ print(e);
+ // toPrint(val: e);
+ }
+ }
+
+ // 安装apk
+ static Future installApk(context, UpdateAppEvent event, UpgradeLogic logic) async {
+ try {
+ logic.loadingApk.value = true;
+ File? _apkFile = await _downloadAndroid(context, event, logic);
+ if (_apkFile == null) return false;
+ String _apkFilePath = _apkFile.path;
+ if (_apkFilePath.isEmpty) {
+ debugPrint('make sure the apk file is set');
+ return false;
+ }
+
+ await showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: const Text("未知应用安装权限提示",
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ )),
+ content: const Text("请注意:更新时若出现需要同意“安装未知应用权限”,请同意!!!"),
+ actions: [
+ MaterialButton(
+ color: Theme.of(context).primaryColor,
+ child: const Text("我已知晓", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ],
+ );
+ },
+ );
+ await AppInstaller.installApk(_apkFilePath); // 安装APK
+ // 如果2秒还没有进入安装引导页面 一律视为更新失败,弹出其他方式更新
+ Utils.getInstance().setTimeOut(1, () async {
+ try {
+ // 其他方式下载
+ // await SystemNavigator.pop(); // 退出APP
+ var options = ['应用市场更新APP', '浏览器下载并安装APP'];
+ var uri = Uri.parse('market://details?id=com.example.marking_app'); // 应用市场URI
+ if (!await canLaunchUrl(uri)) options.removeAt(0); // 如果不能打开应用市场 就屏蔽掉 这个安装方式
+ String? option = await UpgradePermission.showCustomModalBottomSheet(context, options);
+ if (option == '应用市场更新APP') await launchUrl(uri);
+ if (option == '浏览器下载并安装APP') await launchUrl(Uri.parse(event.link));
+ } catch (e) {}
+ });
+
+ print('安装执行完成了..............0.0');
+ } catch (e) {
+ print('安装进入报错....');
+ print(e);
+ } finally {
+ logic.loadingApk.value = false;
+ }
+
+ return false;
+ }
+
+ /// 展示下载进度
+ static void showDownloadProgress(context, num received, num total, UpgradeLogic logic) {
+ if (total != -1) {
+ double progress = double.parse((received / total).toStringAsFixed(2));
+ // debugPrint('下载进度$progress');
+ logic.downloadRatio.value = progress;
+ }
+ }
+}
+
+class RestartWidget extends StatefulWidget {
+ final Widget child;
+
+ const RestartWidget({super.key, required this.child});
+
+ static restartApp(BuildContext context) {
+ final _RestartWidgetState? state = context.findAncestorStateOfType<_RestartWidgetState>();
+ state?.restartApp();
+ }
+
+ @override
+ State createState() => _RestartWidgetState();
+}
+
+class _RestartWidgetState extends State {
+ Key key = UniqueKey();
+
+ void restartApp() {
+ setState(() {
+ key = UniqueKey();
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return KeyedSubtree(
+ key: key,
+ child: widget.child,
+ );
+ }
+}
diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/UpdateDialog.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/UpdateDialog.dart
new file mode 100644
index 0000000..4d41354
--- /dev/null
+++ b/making_school_asignment_app/lib/common/utils/app_upgrade/UpdateDialog.dart
@@ -0,0 +1,212 @@
+/*
+ * @Author: wangyang 1147192855@qq.com
+ * @Date:
+ * @LastEditors: wangyang 1147192855@qq.com
+ * @LastEditTime: 2022-09-29 10:11:54
+ * @FilePath: \marking_app\lib\utils\app_upgrade\UpdateDialog.dart
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/*
+ * @Descripttion: 版本更新提示弹窗
+ * @version:
+ * @Author: wy
+ * @Date: 2020-07-30 14:03:28
+ * @LastEditors: Please set LastEditors
+ * @LastEditTime: 2021-01-12 15:08:43
+ */
+import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
+import 'package:get/get.dart';
+import 'package:making_school_asignment_app/common/utils/app_upgrade/DownloadApk.dart';
+import 'package:making_school_asignment_app/common/utils/app_upgrade/UpgradePermission.dart';
+import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart';
+import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
+import 'package:percent_indicator/linear_percent_indicator.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:url_launcher/url_launcher.dart';
+import 'package:url_launcher/url_launcher_string.dart';
+
+import '../anti_shake_throttling.dart';
+import 'model/UpdateAppEvent.dart';
+
+class UpdateDialog extends Dialog {
+ final UpdateAppEvent updateAppEvent;
+ final String deviceInfo;
+
+ const UpdateDialog({super.key, required this.updateAppEvent, required this.deviceInfo});
+
+ @override
+ Widget build(BuildContext context) {
+ return Center(
+ child: Container(
+ width: 319.w,
+ height: 440.h,
+ padding: EdgeInsets.symmetric(vertical: 8.h),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(18.sp),
+ image: const DecorationImage(
+ alignment: Alignment.topCenter,
+ image: AssetImage("assets/images/upgrade_dialog_bgc.png"),
+ fit: BoxFit.fitWidth,
+ ),
+ ),
+ child: Column(
+ children: [
+ Expanded(
+ child: ListView(
+ physics: const BouncingScrollPhysics(),
+ padding: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0),
+ children: [
+ Container(
+ alignment: Alignment.center,
+ margin: EdgeInsets.only(top: 128.h, bottom: 10.h),
+ child: quickText(
+ updateAppEvent.title,
+ size: 18.sp,
+ fontWeight: FontWeight.w600,
+ color: const Color.fromRGBO(58, 90, 159, 1),
+ ),
+ ),
+ HtmlWidget(
+ updateAppEvent.description,
+ customStylesBuilder: (element) {
+ return {'color': '#666666', 'font-weight': 'normal', 'text-decoration': 'none'};
+ },
+ onLoadingBuilder: (context, element, loadingProgress) => const CircularProgressIndicator(),
+ renderMode: RenderMode.column,
+ textStyle: TextStyle(fontSize: 14.sp, color: Colors.black87),
+ )
+ ],
+ ),
+ ),
+ DownloadProgress(),
+ DownloadButton(updateAppEvent, deviceInfo: deviceInfo),
+ ],
+ ),
+ ),
+ );
+ }
+
+ // 调起
+ static showUpdateDialog(BuildContext context, UpdateAppEvent updateAppEvent) {
+ return showDialog(
+ barrierDismissible: false,
+ context: context,
+ builder: (BuildContext context) {
+ return WillPopScope(
+ onWillPop: () async => false,
+ child: UpdateDialog(updateAppEvent: updateAppEvent, deviceInfo: updateAppEvent.deviceInfo),
+ );
+ },
+ );
+ }
+}
+
+// 进度条
+class DownloadProgress extends StatelessWidget {
+ DownloadProgress({super.key});
+ final logic = Get.find();
+
+ @override
+ Widget build(BuildContext context) {
+ return Obx(() {
+ var str = (logic.downloadRatio.value * 100).toString().split('.')[0];
+ if (logic.downloadRatio.value <= 0) return Container();
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ LinearPercentIndicator(
+ alignment: MainAxisAlignment.center,
+ width: 245.w,
+ animation: false,
+ lineHeight: 20.0.h,
+ percent: logic.downloadRatio.value,
+ center: quickText(
+ "$str%",
+ size: 14.sp,
+ align: TextAlign.center,
+ color: Colors.white,
+ ),
+ linearStrokeCap: LinearStrokeCap.roundAll,
+ progressColor: Theme.of(context).primaryColor,
+ ),
+ Container(
+ height: 6.h,
+ ),
+ quickText('更新中...', size: 12.sp, fontWeight: FontWeight.w500, color: const Color.fromRGBO(90, 90, 90, 1))
+ ],
+ );
+ });
+ }
+}
+
+// 点击下载按钮
+class DownloadButton extends StatelessWidget {
+ final UpdateAppEvent updateAppEvent;
+ final String deviceInfo;
+ DownloadButton(this.updateAppEvent, {required this.deviceInfo, super.key});
+ final logic = Get.find();
+
+ // 打开浏览器或者对应的对应市场进行下载
+ Future toLaunch(UpdateAppEvent data) async {
+ var uri = Uri.parse('market://details?id=com.yuanxuan.making_school_asignment_app');
+ if (await canLaunchUrl(uri)) {
+ // 跳进对应的应用市场进行更新操作
+ return await launchUrl(uri);
+ }
+ // 无法进入应用市场就打开浏览器进行下载
+ uri = Uri.parse(data.link);
+ if (await canLaunchUrl(uri)) return await launchUrl(uri);
+ return false;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Obx(() {
+ final count = logic.downloadRatio.value;
+ if (count > 0) return Container();
+ var primaryColor = Theme.of(context).primaryColor;
+ return Container(
+ height: 38.h,
+ width: 245.w,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(42.h)),
+ gradient: LinearGradient(colors: [
+ primaryColor,
+ primaryColor.withOpacity(0.7),
+ ]),
+ ),
+ child: MaterialButton(
+ onPressed: () => easyThrottle('DownloadButton_App_Upgrade', duration: const Duration(milliseconds: 1000), () async {
+ if (deviceInfo == "android" && updateAppEvent.equipment == Equipment.android) {
+ // 权限检查 判断是否有读写内存的权限
+ bool flag = await UpgradePermission(updateAppEvent.deviceInfo).checkPermission(context, updateAppEvent);
+ if (flag) {
+ flag = await DownloadApk.installApk(context, updateAppEvent, logic);
+ if (!flag) {
+ print('执行到了重置更新按钮的地方....');
+ logic.downloadRatio.value = 0.0; // 更新失败重置 更新按钮
+ } else {
+ print('更新成功重新打开APP..............');
+ RestartWidget.restartApp(context); // 安装成功 重启APP
+ }
+ return;
+ }
+ // await FlutterClipboard.copy(updateAppEvent.link);
+ // setTimeOut(1000, () => ToastUtils.showInfo('下载链接已经复制到设备,可前往浏览器下载安装'));
+ } else if (deviceInfo == "ios" && updateAppEvent.equipment == Equipment.ios) {
+ try {
+ await launchUrlString(updateAppEvent.link);
+ } catch (e) {
+ print('进来更新报错$e');
+ }
+ }
+ }),
+ child: quickText(!logic.loadingApk.value ? '立即体验' : '正在下载...', size: 16.sp, color: Colors.white, fontWeight: FontWeight.w500),
+ ),
+ );
+ });
+ }
+}
diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/UpgradePermission.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/UpgradePermission.dart
new file mode 100644
index 0000000..eaa6dda
--- /dev/null
+++ b/making_school_asignment_app/lib/common/utils/app_upgrade/UpgradePermission.dart
@@ -0,0 +1,142 @@
+/*
+ * @Descripttion: 获取本地权限
+ * @version: UpgradePermission
+ * @Author: wy
+ * @Date: 2020-07-30 15:41:39
+ * @LastEditors: wangyang 1147192855@qq.com
+ * @LastEditTime: 2022-08-01 14:08:57
+ */
+import 'package:app_installer/app_installer.dart';
+import 'package:flutter/material.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import 'model/UpdateAppEvent.dart';
+
+class UpgradePermission {
+ final String _flatform;
+ const UpgradePermission(this._flatform);
+
+ /// 检查是否有权限,用于安卓
+ /// noExecutions 执行次数
+ Future checkPermission(BuildContext context, UpdateAppEvent updateAppEvent, [int? noExecutions]) async {
+ noExecutions ??= 1;
+ if (_flatform != 'android') return true; // 非安卓
+ var status = await Permission.storage.request();
+ if (status.isGranted) return true;
+
+ if (status.isDenied) {
+ // 普通拒绝 可以再进行提示
+
+ await showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: const Text("权限提示"),
+ content: const Text("无法获取存储权限,请同意获取设备存储权限"),
+ actions: [
+ MaterialButton(
+ color: Theme.of(context).primaryColor,
+ child: const Text("同意", style: TextStyle(color: Colors.white)),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ],
+ );
+ },
+ );
+
+ if (noExecutions < 2) return checkPermission(context, updateAppEvent, ++noExecutions);
+ // 执行次数大于2次,就不再询问直接打开设置权限页面(防止某些机型不会弹起权限询问交互弹框)
+ }
+
+ // 拒绝并不再提示
+ bool? res = await showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: const Text("权限提示"),
+ content: const Text("储存权限被永久拒绝,并且不再提示。请前往设置页面同意储存权限"),
+ actions: [
+ MaterialButton(
+ color: Colors.green.shade900,
+ child: const Text("其它方式更新", style: TextStyle(color: Colors.white)),
+ onPressed: () => Navigator.of(context).pop(false),
+ ),
+ MaterialButton(
+ color: Theme.of(context).primaryColor,
+ child: const Text("前往设置", style: TextStyle(color: Colors.white)),
+ onPressed: () => Navigator.of(context).pop(true),
+ ),
+ ],
+ );
+ },
+ );
+ if (res == null || !res) {
+ // 其他方式下载
+ // await SystemNavigator.pop(); // 退出APP
+ var options = ['应用市场更新APP', '浏览器下载并安装APP'];
+ var uri = Uri.parse('market://details?id=com.example.marking_app'); // 应用市场URI
+ // if (!await canLaunchUrl(uri)) options.removeAt(0); // 如果不能打开应用市场 就屏蔽掉 这个安装方式
+ String? option = await showCustomModalBottomSheet(context, options);
+ if (option == '应用市场更新APP') {
+ if (await canLaunchUrl(uri))
+ await launchUrl(uri);
+ else
+ await AppInstaller.goStore('com.example.marking_app', 'iOSAppId');
+ }
+ if (option == '浏览器下载并安装APP') await launchUrl(Uri.parse(updateAppEvent.link));
+ } else
+ await openAppSettings();
+ return false;
+ }
+
+ // 其他方式下载选择
+ static Future showCustomModalBottomSheet(context, List options) async {
+ return showModalBottomSheet(
+ backgroundColor: Colors.transparent,
+ isScrollControlled: true,
+ context: context,
+ builder: (BuildContext context) {
+ return Container(
+ clipBehavior: Clip.antiAlias,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.only(
+ topLeft: const Radius.circular(20.0),
+ topRight: const Radius.circular(20.0),
+ ),
+ ),
+ height: MediaQuery.of(context).size.height / 4.0,
+ child: Column(children: [
+ SizedBox(
+ height: 50,
+ child: Stack(
+ textDirection: TextDirection.rtl,
+ children: [
+ Center(child: Text('选择其它方式更新APP', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0))),
+ IconButton(icon: Icon(Icons.close), onPressed: () => Navigator.of(context).pop()),
+ ],
+ ),
+ ),
+ Divider(height: 1.0),
+ Expanded(
+ child: ListView.builder(
+ itemCount: options.length,
+ itemBuilder: (BuildContext context, int index) {
+ var name = options[index];
+ return ListTile(
+ title: Text(name),
+ trailing: Icon(name.contains('浏览器') ? Icons.browser_updated_outlined : Icons.local_grocery_store_outlined),
+ onTap: () => Navigator.of(context).pop(name),
+ );
+ },
+ ),
+ ),
+ ]),
+ );
+ },
+ );
+ }
+}
diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/model/UpdateAppEvent.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/model/UpdateAppEvent.dart
new file mode 100644
index 0000000..581721f
--- /dev/null
+++ b/making_school_asignment_app/lib/common/utils/app_upgrade/model/UpdateAppEvent.dart
@@ -0,0 +1,83 @@
+/*
+ * @Descripttion:
+ * @version:
+ * @Author: wy
+ * @Date: 2020-07-30 14:10:44
+ * @LastEditors: wangyang 1147192855@qq.com
+ * @LastEditTime: 2022-09-28 18:20:11
+ */
+
+class UpdateAppEvent {
+ final String version;
+ final String title;
+ final String description;
+ final String link;
+ final bool upgrade;
+ final String deviceInfo;
+ final String appName;
+ final String packageName;
+ final Equipment equipment;
+ num? v;
+ num? lv;
+
+ UpdateAppEvent({
+ required this.version,
+ required this.title,
+ required this.description,
+ required this.link,
+ required this.upgrade,
+ required this.deviceInfo,
+ required this.appName,
+ required this.packageName,
+ this.v,
+ this.lv,
+ int type = 0,
+ }) : equipment = Equipment.values[type];
+
+ factory UpdateAppEvent.fromJson(Map json, String localVersion, String deviceInfo, String appName, String packageName,
+ {String keyStr = "version", String typeName = "packageNameType"}) {
+ String version = json[keyStr]; // 版本号
+ String? descriptionStr = json["description"];
+
+ String newDescription = '系统有更新,请立即下载';
+ bool upgrade = false;
+ num? v;
+ num? lv;
+ // 版本号
+ if (version != '') {
+ v = num.parse(version.replaceAll(".", ""));
+ lv = num.parse(localVersion.replaceAll(".", ""));
+
+ // if (lv < v) upgrade = true;
+ //当前版本不等于线上版本更新为线上版本
+ if (lv != v) upgrade = true;
+ }
+
+ // 升级说明
+ if (descriptionStr != null && descriptionStr.isNotEmpty) {
+ newDescription = descriptionStr;
+ }
+
+ return UpdateAppEvent(
+ version: version, // 版本号
+ title: json["title"] ?? "发现新版本", // title
+ description: newDescription, //说明
+ link: json["downloadPath"], // 链接地址
+ upgrade: upgrade,
+ deviceInfo: deviceInfo,
+ appName: appName,
+ packageName: packageName,
+ type: json[typeName] ?? 0,
+ v: v,
+ lv: lv,
+ );
+ }
+
+ @override
+ String toString() {
+ return "UpdateAppEvent { version: $version, title: $title, description: $description, link: $link}";
+ }
+}
+
+// 设备枚举
+enum Equipment { other, android, ios }
diff --git a/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart b/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart
new file mode 100644
index 0000000..8bd7ee6
--- /dev/null
+++ b/making_school_asignment_app/lib/common/utils/app_upgrade/upgradeLogic.dart
@@ -0,0 +1,63 @@
+import 'dart:io';
+import 'package:flutter/widgets.dart';
+import 'package:get/get.dart';
+import 'package:making_school_asignment_app/common/job/app_version.dart';
+import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+
+import 'UpdateDialog.dart';
+import 'model/UpdateAppEvent.dart';
+
+class UpgradeLogic extends GetxController with RequestToolMixin {
+ Rx showUpgrade = false.obs; // 是否已经显示升级弹窗
+ Rx loadingApk = false.obs; // 是否已经显示升级弹窗
+ Rx downloadRatio = 0.0.obs; // 下载比例
+
+ // @override
+ // void onInit() {
+
+ // super.onInit();
+ // }
+
+ void getAppUpgrade(BuildContext context) async {
+ // if (!const bool.fromEnvironment('dart.vm.product')) return;
+ try {
+ showUpgrade.value = true;
+ // if (['18888888888'].contains(user.loginName)) return;
+ // 获取设备信息
+ String deviceInfo;
+ int deviceType;
+ if (Platform.isAndroid) {
+ deviceInfo = "android";
+ deviceType = 1;
+ } else if (Platform.isIOS) {
+ deviceInfo = "ios";
+ deviceType = 2;
+ } else {
+ return;
+ }
+
+ AppVersion? result = await getClient().getLastAppVersion('making_school_asignment_app', deviceType);
+ if (result != null) {
+ //获取当前版本
+ PackageInfo packageInfo = await PackageInfo.fromPlatform();
+ //获取当前版本
+ String localVersion = packageInfo.version;
+ String appName = packageInfo.appName; //应用名称
+ String packageName = packageInfo.packageName; //包名称
+ // String buildNumber = packageInfo.buildNumber; //小版本号
+
+ Map json = {
+ 'downloadPath': result.downloadUrl,
+ 'version': result.version,
+ 'systemType': deviceType,
+ 'description': result.description ?? 'APP新版本更新'
+ };
+ UpdateAppEvent updateAppEvent = UpdateAppEvent.fromJson(json, localVersion, deviceInfo, appName, packageName, typeName: 'systemType');
+ if (updateAppEvent.upgrade) await UpdateDialog.showUpdateDialog(context, updateAppEvent);
+ }
+ } finally {
+ showUpgrade.value = false;
+ }
+ }
+}
diff --git a/making_school_asignment_app/lib/common/utils/utils.dart b/making_school_asignment_app/lib/common/utils/utils.dart
index dcfed42..d59af4e 100644
--- a/making_school_asignment_app/lib/common/utils/utils.dart
+++ b/making_school_asignment_app/lib/common/utils/utils.dart
@@ -7,7 +7,13 @@ import 'package:making_school_asignment_app/page/home_page/children/quick_data_c
import 'dart:math';
class Utils {
+ static Utils? _instance;
Utils._internal();
+ static Utils getInstance() {
+ _instance ??= Utils._internal();
+
+ return _instance!;
+ }
/// 关闭键盘
static void hideKeyboard() {
@@ -20,6 +26,8 @@ class Utils {
}
}
+ void setTimeOut(int seconds, call) => Future.delayed(Duration(seconds: seconds), call);
+
// 是否是平板
static bool isPad([double mobilePhoneScale = 1.2]) {
return ScreenUtil().scaleWidth > mobilePhoneScale;
@@ -82,38 +90,26 @@ class Utils {
dataCount.kgtAnswerCount = kgt.where((w) => w.state != 0).length;
dataCount.kgtOkCount = kgt.where((w) => w.state == 3).length;
dataCount.kgtDtlCount = kgt.length;
- dataCount.kgtAnswerRate =
- Utils.calcRate(dataCount.kgtAnswerCount!, dataCount.kgtDtlCount!);
- dataCount.kgtOkRate =
- Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtDtlCount!);
- dataCount.kgtCount =
- data.questions.where((w) => w.questionType == 1).length;
+ dataCount.kgtAnswerRate = Utils.calcRate(dataCount.kgtAnswerCount!, dataCount.kgtDtlCount!);
+ dataCount.kgtOkRate = Utils.calcRate(dataCount.kgtOkCount!, dataCount.kgtDtlCount!);
+ dataCount.kgtCount = data.questions.where((w) => w.questionType == 1).length;
List zgt = data.dtls.where((w) => w.questionType == 2).toList();
dataCount.zgtAnswerCount = zgt.where((w) => w.state != 0).length;
dataCount.zgtOkCount = zgt.where((w) => w.state == 3).length;
dataCount.zgtDtlCount = zgt.length;
- dataCount.zgtAnswerRate =
- Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!);
- dataCount.zgtOkRate =
- Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!);
- dataCount.zgtCount =
- data.questions.where((w) => w.questionType == 2).length;
+ dataCount.zgtAnswerRate = Utils.calcRate(dataCount.zgtAnswerCount!, dataCount.zgtDtlCount!);
+ dataCount.zgtOkRate = Utils.calcRate(dataCount.zgtOkCount!, dataCount.zgtDtlCount!);
+ dataCount.zgtCount = data.questions.where((w) => w.questionType == 2).length;
dataCount.studentCount = data.students.length;
- dataCount.priorityStudents =
- data.students.where((w) => w.priorityAnnotate!).toList();
-
+ dataCount.priorityStudents = data.students.where((w) => w.priorityAnnotate!).toList();
//已提交学生数
- dataCount.studentSubmitCount =
- data.students.where((s) => s.state != 0).length;
- dataCount.studentSubmitStudents =
- data.students.where((s) => s.state != 0).toList();
+ dataCount.studentSubmitCount = data.students.where((s) => s.state != 0).length;
+ dataCount.studentSubmitStudents = data.students.where((s) => s.state != 0).toList();
//未提交学生数
- dataCount.noAnswerCount =
- data.students.length - dataCount.studentSubmitCount!;
- dataCount.noAnswerStudents =
- data.students.where((s) => s.state == 0).toList();
+ dataCount.noAnswerCount = data.students.length - dataCount.studentSubmitCount!;
+ dataCount.noAnswerStudents = data.students.where((s) => s.state == 0).toList();
for (var stu in data.students) {
stu.kgtStu = kgt.where((w) => w.studentId == stu.studentId).toList();
@@ -128,17 +124,13 @@ class Utils {
stu.zgtErrorCount = stu.zgtStu!.where((w) => w.state == 2).length;
stu.zgtUnrated = stu.zgtStu!.where((w) => w.state == 1).length;
stu.zgtAnswerCount = stu.zgtStu!.where((w) => w.state != 0).length;
- stu.isAllCorrect =
- stu.kgtOkCount! + stu.zgtOkCount! == kgt.length + zgt.length
- ? true
- : false;
+ stu.isAllCorrect = stu.kgtOkCount! + stu.zgtOkCount! == kgt.length + zgt.length ? true : false;
stu.allOk = data.dtls.where((w) {
if (stu.studentId == w.studentId) {
stu.useTime = w.useTime;
}
for (var que in data.questions) {
- if (w.templateId == que.templateId &&
- w.questionNo == que.questionNo) {
+ if (w.templateId == que.templateId && w.questionNo == que.questionNo) {
w.answer = que.answer;
w.questionPicture = que.questionPicture;
}
@@ -146,25 +138,16 @@ class Utils {
return w.studentId == stu.studentId && w.state != 3;
}).length ??
0;
- if ((stu.kgtStu!.length - stu.kgtAnswerCount!) +
- (stu.zgtStu!.length - stu.zgtAnswerCount!) ==
- (stu.kgtStu!.length + stu.zgtStu!.length)) {
+ if ((stu.kgtStu!.length - stu.kgtAnswerCount!) + (stu.zgtStu!.length - stu.zgtAnswerCount!) == (stu.kgtStu!.length + stu.zgtStu!.length)) {
stu.allNotDone = true;
} else {
stu.allNotDone = false;
}
- stu.noAnswerCount = data.dtls
- .where((w) => w.state == 0 && stu.studentId == w.studentId)
- .length;
+ stu.noAnswerCount = data.dtls.where((w) => w.state == 0 && stu.studentId == w.studentId).length;
List ques = data.questions;
stu.queDtls = data.dtls
- .where((w) =>
- w.studentId == stu.studentId &&
- ques.indexWhere((q) =>
- w.templateId == q.templateId &&
- w.questionNo == q.questionNo) >
- -1)
+ .where((w) => w.studentId == stu.studentId && ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1)
.toList();
int okCount = stu.queDtls!.where((w) => w.state == 3).length;
int ttlCount = stu.queDtls!.length;
@@ -177,57 +160,41 @@ class Utils {
return num2.compareTo(num1);
});
//全对
- dataCount.allCorrect =
- data.students.where((w) => w.isAllCorrect == true).length;
- dataCount.allCorrectStudents =
- data.students.where((w) => w.isAllCorrect == true).toList();
+ dataCount.allCorrect = data.students.where((w) => w.isAllCorrect == true).length;
+ dataCount.allCorrectStudents = data.students.where((w) => w.isAllCorrect == true).toList();
//优
- dataCount.levelOneCount =
- data.students.where((s) => s.okRate! >= 85).length;
- dataCount.levelOneStudents =
- data.students.where((s) => s.okRate! >= 85).toList();
+ dataCount.levelOneCount = data.students.where((s) => s.okRate! >= 85).length;
+ dataCount.levelOneStudents = data.students.where((s) => s.okRate! >= 85).toList();
//良
- dataCount.levelTwoCount =
- data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).length;
- dataCount.levelTwoStudents =
- data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).toList();
+ dataCount.levelTwoCount = data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).length;
+ dataCount.levelTwoStudents = data.students.where((s) => s.okRate! < 85 && s.okRate! >= 55).toList();
//中
- dataCount.levelThreeCount =
- data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).length;
- dataCount.levelThreeStudents =
- data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).toList();
+ dataCount.levelThreeCount = data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).length;
+ dataCount.levelThreeStudents = data.students.where((s) => s.okRate! < 55 && s.okRate! >= 25).toList();
//差
- dataCount.levelFourCount =
- data.students.where((s) => s.okRate! < 25).length;
- dataCount.levelFourStudents =
- data.students.where((s) => s.okRate! < 25).toList();
+ dataCount.levelFourCount = data.students.where((s) => s.okRate! < 25).length;
+ dataCount.levelFourStudents = data.students.where((s) => s.okRate! < 25).toList();
for (var que in data.questions) {
- List ques = data.dtls
- .where((w) =>
- w.templateId == que.templateId && w.questionNo == que.questionNo)
- .toList();
+ List ques = data.dtls.where((w) => w.templateId == que.templateId && w.questionNo == que.questionNo).toList();
que.answerCount = ques.where((w) => w.state != 0).length;
- que.answerRate =
- Utils.calcRate(que.answerCount!, dataCount.studentCount!);
+ que.answerRate = Utils.calcRate(que.answerCount!, dataCount.studentCount!);
int okCount = ques.where((w) => w.state == 3).length;
que.okRate = Utils.calcRate(okCount, dataCount.studentCount!);
que.priorityInfo = ques.where((w) {
return dataCount.priorityStudents!.indexWhere((s) {
- w.studentName = s.studentName;
- return s.studentId == w.studentId;
- }) >
- -1 &&
+ w.studentName = s.studentName;
+ return s.studentId == w.studentId;
+ }) >
+ -1 &&
w.state != 3;
}).toList();
que.answerNgStudents = ques.where((w) {
- w.studentName = data.students
- .firstWhere((s) => s.studentId == w.studentId)
- .studentName;
+ w.studentName = data.students.firstWhere((s) => s.studentId == w.studentId).studentName;
return w.state == 2;
}).toList();
@@ -238,18 +205,14 @@ class Utils {
return w.state == 3;
}).toList();
-
//作答效率
int middleTime = 0;
if (ques.length % 2 == 0) {
int index = (ques.length / 2).ceil();
- middleTime = ((ques[index].useTime +
- ques[index - 1].useTime) /
- 2)
- .ceil();
+ middleTime = ((ques[index].useTime + ques[index - 1].useTime) / 2).ceil();
} else {
- int index = ((ques.length + 1) / 2).ceil() ;
- middleTime = ques[index - 1 ].useTime;
+ int index = ((ques.length + 1) / 2).ceil();
+ middleTime = ques[index - 1].useTime;
}
var excellent = ques.where((w) => w.state == 3 && w.useTime <= middleTime).length;
@@ -257,26 +220,12 @@ class Utils {
var middle = ques.where((w) => w.state != 3 && w.useTime <= middleTime).length;
var differ = ques.where((w) => w.state != 3 && w.useTime > middleTime).length;
- que.overallTitles = [OverallTitles('优秀',excellent),OverallTitles('良好',good),
- OverallTitles('中',middle),OverallTitles('差',differ)];
-
-
+ que.overallTitles = [OverallTitles('优秀', excellent), OverallTitles('良好', good), OverallTitles('中', middle), OverallTitles('差', differ)];
}
-
-
for (var know in data.knows) {
- List ques = data.questions
- .where((w) =>
- w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1)
- .toList();
- List queDtls = data.dtls
- .where((w) =>
- ques.indexWhere((q) =>
- w.templateId == q.templateId &&
- w.questionNo == q.questionNo) >
- -1)
- .toList();
+ List ques = data.questions.where((w) => w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1).toList();
+ List queDtls = data.dtls.where((w) => ques.indexWhere((q) => w.templateId == q.templateId && w.questionNo == q.questionNo) > -1).toList();
know.okCount = queDtls.where((w) => w.state == 3).length;
know.ttlCount = queDtls.length;
know.okRate = Utils.calcRate(know.okCount!, know.ttlCount!);
@@ -311,7 +260,6 @@ bool isPad([double mobilePhoneScale = 1.2]) {
return ScreenUtil().scaleWidth > mobilePhoneScale;
}
-void toUpState(
- Function(void Function()) setState, VoidCallback fn, bool mounted) {
+void toUpState(Function(void Function()) setState, VoidCallback fn, bool mounted) {
if (mounted) setState(fn);
-}
\ No newline at end of file
+}
diff --git a/making_school_asignment_app/lib/main.dart b/making_school_asignment_app/lib/main.dart
index 414aa32..477f302 100644
--- a/making_school_asignment_app/lib/main.dart
+++ b/making_school_asignment_app/lib/main.dart
@@ -11,6 +11,8 @@ import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'common/utils/app_upgrade/upgradeLogic.dart';
+
void main() async {
// 在测试模式下运行Get
Get.testMode = true;
@@ -20,6 +22,7 @@ void main() async {
/// 初始化UserStore
Get.put(UserStore().init());
+ Get.put(UpgradeLogic());
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //状态栏背景颜色
diff --git a/making_school_asignment_app/lib/page/global_widget/start_page.dart b/making_school_asignment_app/lib/page/global_widget/start_page.dart
index 1b6953c..f978920 100644
--- a/making_school_asignment_app/lib/page/global_widget/start_page.dart
+++ b/making_school_asignment_app/lib/page/global_widget/start_page.dart
@@ -1,17 +1,14 @@
-import 'dart:io';
+import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
-import 'package:package_info_plus/package_info_plus.dart';
-import 'package:making_school_asignment_app/common/config/app_config.dart';
-import 'package:making_school_asignment_app/common/job/common/app_version_model.dart';
-import 'package:making_school_asignment_app/common/job/common/base_app_version.dart';
-import 'package:making_school_asignment_app/common/job/common/base_page_data.dart';
+import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart';
import 'package:making_school_asignment_app/common/job/user_info.dart';
import 'package:making_school_asignment_app/common/job/user_info_detail.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/store/user_store.dart';
+import 'package:making_school_asignment_app/common/utils/storage.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/page/home_page/children/my_info.dart';
import 'package:making_school_asignment_app/page/home_page/home_logic.dart';
@@ -27,22 +24,30 @@ class StartPage extends StatefulWidget {
State createState() => _StartPageState();
}
-class _StartPageState extends State {
+class _StartPageState extends State with RequestToolMixin {
+ Timer? _timer;
DateTime? lastPopTime;
final _pageController = Get.find();
+ final _upgradeLogic = Get.find();
+
late final List _bodyList;
@override
void initState() {
super.initState();
+
Get.put(HomeLogic());
Get.put(WorkLogic());
- _bodyList = [
- const HomePage(),
- const WorkPage(),
- const MyInfo(),
- ];
+ _bodyList = [const HomePage(), const WorkPage(), const MyInfo()];
+ // TODO 启动APP 后直接请求更新
+ if (!_upgradeLogic.showUpgrade.value) _upgradeLogic.getAppUpgrade(context);
+
+ _timer?.cancel();
+ _timer = Timer.periodic(const Duration(seconds: 40), (e) {
+ if (Get.currentRoute == Routes.login) return; // 在登录页面不更新APP
+ if (!_upgradeLogic.showUpgrade.value) _upgradeLogic.getAppUpgrade(context);
+ });
String? token = UserStore.to.token;
UserInfo? userInfo = UserStore.to.userInfo.value;
@@ -55,13 +60,18 @@ class _StartPageState extends State {
// 更新用户信息
if (userInfoDetail == null) UserStore.to.updateUserInfo();
} else {
- Future.delayed(const Duration(milliseconds: 100)).then((e) => Get.offAllNamed(Routes.login));
+ Future.delayed(const Duration(milliseconds: 100)).then((e) {
+ UserStore.to.erase();
+ StorageService.to.erase();
+ Get.offAllNamed(Routes.login);
+ });
}
}
@override
void dispose() {
Get.delete();
+ _timer?.cancel();
super.dispose();
}
@@ -146,44 +156,6 @@ class PageIndexState {
class PageIndexController extends GetxController with RequestToolMixin {
late PageIndexState _pageIndexState;
- void getAppUpgrade(UserInfoDetail user) async {
- try {
- _pageIndexState.showUpgrade = true;
- if (user.name == AppConfig.SKIP_UPDATING_USER) return;
- // 获取设备信息
- String deviceInfo = "android";
- int deviceType;
- if (Platform.isAndroid) {
- deviceType = 1;
- } else if (Platform.isIOS) {
- deviceInfo = "ios";
- deviceType = 2;
- } else {
- return;
- }
- var params = BaseAppVersion(AppConfig.APP_NAME, deviceType, 1, 1);
- BasePageData? result = await getClient().getAppVersions(params);
- if (result != null && result.total == 1) {
- //获取当前版本
- PackageInfo packageInfo = await PackageInfo.fromPlatform();
- //获取当前版本
- String localVersion = packageInfo.version;
- String appName = packageInfo.appName; //应用名称
- String packageName = packageInfo.packageName; //包名称
- // String buildNumber = packageInfo.buildNumber; //小版本号
- AppVersionModel data = result.items[0];
- // Map json = {'downloadPath': data.apkUrl, 'version': data.version, 'systemType': deviceType, 'description': data.description};
- // UpdateAppEvent updateAppEvent = UpdateAppEvent.fromJson(json, localVersion, deviceInfo, appName, packageName, typeName: 'systemType');
- // if (updateAppEvent.upgrade) {
- // await UpdateDialog.showUpdateDialog(context, updateAppEvent);
- // }
- }
- } catch (e) {
- } finally {
- _pageIndexState.showUpgrade = false;
- }
- }
-
@override
void onInit() {
_pageIndexState = PageIndexState(pageController: PageController());
diff --git a/making_school_asignment_app/lib/page/home_page/children/job_report/widget/top_count.dart b/making_school_asignment_app/lib/page/home_page/children/job_report/widget/top_count.dart
index 7d95009..1f6a954 100644
--- a/making_school_asignment_app/lib/page/home_page/children/job_report/widget/top_count.dart
+++ b/making_school_asignment_app/lib/page/home_page/children/job_report/widget/top_count.dart
@@ -6,6 +6,7 @@ import 'package:making_school_asignment_app/page/global_widget/MyEmptyWidget.dar
import 'package:making_school_asignment_app/page/global_widget/show_student_list.dart';
import 'package:making_school_asignment_app/page/home_page/children/quick_data_check/quick_data_check_state.dart';
+part 'top_count.g.dart';
class TopCount extends StatelessWidget {
final CountData data;
@@ -14,7 +15,7 @@ class TopCount extends StatelessWidget {
const TopCount(this.data, this.className, this.jobId, {Key? key}) : super(key: key);
- void showStudentListDialog({required BuildContext context, required String title, required List students}) {
+ void showStudentListDialog({required BuildContext context, required String title, required List students}) {
showDialog(
context: context,
builder: (BuildContext context) {
@@ -58,11 +59,11 @@ class TopCount extends StatelessWidget {
AnswerOkStudents item = arr[index];
return InkWell(
onTap: () {
- *//*RouterManager.router.navigateTo(
+ */ /*RouterManager.router.navigateTo(
context,
RouterManager.quickCheckPersonalPath + '?jobId=$jobId&studentId=${item.id}',
transition: getTransition(),
- );*//*
+ );*/ /*
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 5.r, horizontal: 15.r),
@@ -142,8 +143,7 @@ class TopCount extends StatelessWidget {
onTap: () {
showStudentListDialog(context: context, title: '中等作业学生', students: data.levelThreeStudents!);
},
- child:
- rightContainer(count: data.levelThreeCount!, bgColor: Color(0xFFD3FF93), nameColor: Color(0xFF3F6605), name: '中'),
+ child: rightContainer(count: data.levelThreeCount!, bgColor: Color(0xFFD3FF93), nameColor: Color(0xFF3F6605), name: '中'),
)),
],
),
@@ -159,16 +159,14 @@ class TopCount extends StatelessWidget {
onTap: () {
showStudentListDialog(context: context, title: '良等作业学生', students: data.levelTwoStudents!);
},
- child:
- rightContainer(count: data.levelTwoCount!, bgColor: Color(0xFFFFC38C), nameColor: Color(0xFFD36500), name: '良'),
+ child: rightContainer(count: data.levelTwoCount!, bgColor: Color(0xFFFFC38C), nameColor: Color(0xFFD36500), name: '良'),
)),
Expanded(
child: InkWell(
onTap: () {
showStudentListDialog(context: context, title: '差等作业学生', students: data.levelFourStudents!);
},
- child:
- rightContainer(count: data.levelFourCount!, bgColor: Color(0xFFFF9D94), nameColor: Color(0xFFD12616), name: '差'),
+ child: rightContainer(count: data.levelFourCount!, bgColor: Color(0xFFFF9D94), nameColor: Color(0xFFD12616), name: '差'),
)),
],
),
diff --git a/making_school_asignment_app/lib/page/login_page/login_view.dart b/making_school_asignment_app/lib/page/login_page/login_view.dart
index 9109e46..27b3c8a 100644
--- a/making_school_asignment_app/lib/page/login_page/login_view.dart
+++ b/making_school_asignment_app/lib/page/login_page/login_view.dart
@@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/const_text.dart';
+import 'package:making_school_asignment_app/common/utils/app_upgrade/upgradeLogic.dart';
import 'package:making_school_asignment_app/common/utils/utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import 'package:making_school_asignment_app/routes/app_pages.dart';
@@ -18,8 +19,21 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State {
final logic = Get.find();
+ final upgradeLogic = Get.find();
final state = Get.find().state;
+ @override
+ void initState() {
+ Future.delayed(Duration.zero, () => upgradeLogic.getAppUpgrade(context));
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ Get.delete();
+ super.dispose();
+ }
+
@override
Widget build(BuildContext context) {
return GestureDetector(
@@ -151,7 +165,7 @@ class _LoginPageState extends State {
decoration: InputDecoration(
hintText: "请输入密码",
prefix: Padding(
- padding: EdgeInsets.only(right:5.r),
+ padding: EdgeInsets.only(right: 5.r),
child: Image.asset(
'assets/images/login_pwd.png',
width: 15.r,
@@ -254,7 +268,7 @@ class _LoginPageState extends State {
Row(
children: [
Container(
- width: 25 .w,
+ width: 25.w,
padding: EdgeInsets.only(right: 0.w),
child: Obx(() {
return Transform.scale(
@@ -301,10 +315,4 @@ class _LoginPageState extends State {
),
);
}
-
- @override
- void dispose() {
- Get.delete();
- super.dispose();
- }
}
diff --git a/making_school_asignment_app/linux/flutter/generated_plugin_registrant.cc b/making_school_asignment_app/linux/flutter/generated_plugin_registrant.cc
index e71a16d..f6f23bf 100644
--- a/making_school_asignment_app/linux/flutter/generated_plugin_registrant.cc
+++ b/making_school_asignment_app/linux/flutter/generated_plugin_registrant.cc
@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
+#include
void fl_register_plugins(FlPluginRegistry* registry) {
+ g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
+ fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
+ url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}
diff --git a/making_school_asignment_app/linux/flutter/generated_plugins.cmake b/making_school_asignment_app/linux/flutter/generated_plugins.cmake
index 2e1de87..f16b4c3 100644
--- a/making_school_asignment_app/linux/flutter/generated_plugins.cmake
+++ b/making_school_asignment_app/linux/flutter/generated_plugins.cmake
@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
diff --git a/making_school_asignment_app/pubspec.yaml b/making_school_asignment_app/pubspec.yaml
index 0fc5086..3cf7843 100644
--- a/making_school_asignment_app/pubspec.yaml
+++ b/making_school_asignment_app/pubspec.yaml
@@ -88,6 +88,9 @@ dependencies:
flutter_echarts: ^2.4.0
# 饼图
flutter_echart: ^2.0.0
+ url_launcher: ^6.1.11
+ app_installer: ^1.1.0
+ permission_handler: ^11.0.1
dev_dependencies:
flutter_test:
diff --git a/making_school_asignment_app/windows/flutter/generated_plugin_registrant.cc b/making_school_asignment_app/windows/flutter/generated_plugin_registrant.cc
index 8777c93..51b78a6 100644
--- a/making_school_asignment_app/windows/flutter/generated_plugin_registrant.cc
+++ b/making_school_asignment_app/windows/flutter/generated_plugin_registrant.cc
@@ -7,8 +7,14 @@
#include "generated_plugin_registrant.h"
#include
+#include
+#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
+ PermissionHandlerWindowsPluginRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/making_school_asignment_app/windows/flutter/generated_plugins.cmake b/making_school_asignment_app/windows/flutter/generated_plugins.cmake
index cc1361d..9678546 100644
--- a/making_school_asignment_app/windows/flutter/generated_plugins.cmake
+++ b/making_school_asignment_app/windows/flutter/generated_plugins.cmake
@@ -4,6 +4,8 @@
list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
+ permission_handler_windows
+ url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST