mcy_new #1
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -31,6 +31,15 @@
|
|||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!-- Provider -->
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
<!-- 访问电话状态 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path path="Android/data/com.yuanxuan.making_school_asignment_app/" name="files_root" />
|
||||
<external-path path="." name="external_storage_root" />
|
||||
</paths>
|
||||
|
|
@ -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<AppVersion?> getLastAppVersion(@Query('appName') String appName, @Query('ftuType') int ftuType); // ftuType 1安卓 2IOS
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<String, dynamic> srcJson) => _$AppVersionFromJson(srcJson);
|
||||
|
||||
Map<String, dynamic> toJson() => _$AppVersionToJson(this);
|
||||
}
|
||||
|
|
@ -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 = '用户登录失效,请重新登录';
|
||||
|
|
|
|||
|
|
@ -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<File?> _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<bool> 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<bool>(
|
||||
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<RestartWidget> createState() => _RestartWidgetState();
|
||||
}
|
||||
|
||||
class _RestartWidgetState extends State<RestartWidget> {
|
||||
Key key = UniqueKey();
|
||||
|
||||
void restartApp() {
|
||||
setState(() {
|
||||
key = UniqueKey();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return KeyedSubtree(
|
||||
key: key,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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: <Widget>[
|
||||
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<UpgradeLogic>();
|
||||
|
||||
@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<UpgradeLogic>();
|
||||
|
||||
// 打开浏览器或者对应的对应市场进行下载
|
||||
Future<bool> 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),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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<bool> 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<bool>(
|
||||
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<bool>(
|
||||
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<String?> showCustomModalBottomSheet(context, List<String> options) async {
|
||||
return showModalBottomSheet<String>(
|
||||
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),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 }
|
||||
|
|
@ -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<bool> showUpgrade = false.obs; // 是否已经显示升级弹窗
|
||||
Rx<bool> loadingApk = false.obs; // 是否已经显示升级弹窗
|
||||
Rx<double> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Dtls> 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<Questions> 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,42 +160,28 @@ 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<Dtls> ques = data.dtls
|
||||
.where((w) =>
|
||||
w.templateId == que.templateId && w.questionNo == que.questionNo)
|
||||
.toList();
|
||||
List<Dtls> 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) {
|
||||
|
|
@ -225,9 +194,7 @@ class Utils {
|
|||
}).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<Questions> ques = data.questions
|
||||
.where((w) =>
|
||||
w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1)
|
||||
.toList();
|
||||
List<Dtls> queDtls = data.dtls
|
||||
.where((w) =>
|
||||
ques.indexWhere((q) =>
|
||||
w.templateId == q.templateId &&
|
||||
w.questionNo == q.questionNo) >
|
||||
-1)
|
||||
.toList();
|
||||
List<Questions> ques = data.questions.where((w) => w.knows.indexWhere((k) => k.knowledgeId == know.knowledgeId) > -1).toList();
|
||||
List<Dtls> 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);
|
||||
}
|
||||
|
|
@ -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>(UserStore().init());
|
||||
Get.put(UpgradeLogic());
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent, //状态栏背景颜色
|
||||
|
|
|
|||
|
|
@ -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<StartPage> createState() => _StartPageState();
|
||||
}
|
||||
|
||||
class _StartPageState extends State<StartPage> {
|
||||
class _StartPageState extends State<StartPage> with RequestToolMixin {
|
||||
Timer? _timer;
|
||||
DateTime? lastPopTime;
|
||||
final _pageController = Get.find<PageIndexController>();
|
||||
final _upgradeLogic = Get.find<UpgradeLogic>();
|
||||
|
||||
late final List<Widget> _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<StartPage> {
|
|||
// 更新用户信息
|
||||
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<PageIndexController>();
|
||||
_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<AppVersionModel>? 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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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: '差'),
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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<LoginPage> {
|
||||
final logic = Get.find<LoginLogic>();
|
||||
final upgradeLogic = Get.find<UpgradeLogic>();
|
||||
final state = Get.find<LoginLogic>().state;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () => upgradeLogic.getAppUpgrade(context));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<LoginLogic>();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
|
|
@ -151,7 +165,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||
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<LoginPage> {
|
|||
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<LoginPage> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<LoginLogic>();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -7,8 +7,14 @@
|
|||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
connectivity_plus
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
|
|
|||
Loading…
Reference in New Issue