下载新版本
This commit is contained in:
parent
36a0e183ff
commit
8cae1ffd7d
|
|
@ -1,8 +1,12 @@
|
|||
import 'package:cashier_reserve/common/print/print.dart';
|
||||
import 'package:cashier_reserve/common/push/push.dart';
|
||||
import 'package:cashier_reserve/data_model/login/login_result.dart';
|
||||
import 'package:cashier_reserve/login/login_view.dart';
|
||||
import 'package:cashier_reserve/model/reserve_model.dart';
|
||||
import 'package:cashier_reserve/model/version_model.dart';
|
||||
import 'package:cashier_reserve/update_version/update_version_view.dart';
|
||||
import 'package:easy_refresh/easy_refresh.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
import '../base/ui.dart';
|
||||
import '../channel/channel_event.dart';
|
||||
|
|
@ -62,6 +66,36 @@ class AppManager {
|
|||
YJPush.presentWidget(globalContext!, const LoginView());
|
||||
}
|
||||
|
||||
static void checkAppVersion() async {
|
||||
final res = await VersionModel.requestNewVersionInfo();
|
||||
yjPrint(res);
|
||||
|
||||
if (res == null || res.version == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
yjPrint("version == ${packageInfo.version}");
|
||||
|
||||
List<String> serverList = res.version!.split(".");
|
||||
List<String> localList = packageInfo.version.split(".");
|
||||
|
||||
if (serverList.length != 3 || localList.length != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
int serverVersion = int.parse(serverList[0]) * 10000 + int.parse(serverList[1]) * 100 + int.parse(serverList[2]);
|
||||
int localVersion = int.parse(localList[0]) * 10000 + int.parse(localList[1]) * 100 + int.parse(localList[2]);
|
||||
|
||||
if (serverVersion <= localVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
yjPrint("serverVersion == $serverVersion, localVersion == $localVersion");
|
||||
|
||||
YJPush.presentWidget(globalContext!, UpdateVersionView(versionModel: res,));
|
||||
}
|
||||
|
||||
static void disposeLoginWidget() {
|
||||
_isAlertLogin = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
import 'dart:convert';
|
||||
|
||||
/// createdAt : 1712455187626
|
||||
/// id : 19
|
||||
/// isUp : 0
|
||||
/// message : "需要更新"
|
||||
/// sel : 1
|
||||
/// source : "PC"
|
||||
/// type : "android"
|
||||
/// updatedAt : 1725353572331
|
||||
/// url : "https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/version/1.4.20.exe"
|
||||
/// version : "1.4.21"
|
||||
|
||||
UpdateVersionModel updateVersionModelFromJson(String str) =>
|
||||
UpdateVersionModel.fromJson(json.decode(str));
|
||||
|
||||
String updateVersionModelToJson(UpdateVersionModel data) =>
|
||||
json.encode(data.toJson());
|
||||
|
||||
class UpdateVersionModel {
|
||||
UpdateVersionModel({
|
||||
num? createdAt,
|
||||
num? id,
|
||||
num? isUp,
|
||||
String? message,
|
||||
num? sel,
|
||||
String? source,
|
||||
String? type,
|
||||
num? updatedAt,
|
||||
String? url,
|
||||
String? version,
|
||||
}) {
|
||||
_createdAt = createdAt;
|
||||
_id = id;
|
||||
_isUp = isUp;
|
||||
_message = message;
|
||||
_sel = sel;
|
||||
_source = source;
|
||||
_type = type;
|
||||
_updatedAt = updatedAt;
|
||||
_url = url;
|
||||
_version = version;
|
||||
}
|
||||
|
||||
UpdateVersionModel.fromJson(dynamic json) {
|
||||
_createdAt = json['createdAt'];
|
||||
_id = json['id'];
|
||||
_isUp = json['isUp'];
|
||||
_message = json['message'];
|
||||
_sel = json['sel'];
|
||||
_source = json['source'];
|
||||
_type = json['type'];
|
||||
_updatedAt = json['updatedAt'];
|
||||
_url = json['url'];
|
||||
_version = json['version'];
|
||||
}
|
||||
|
||||
num? _createdAt;
|
||||
num? _id;
|
||||
num? _isUp;
|
||||
String? _message;
|
||||
num? _sel;
|
||||
String? _source;
|
||||
String? _type;
|
||||
num? _updatedAt;
|
||||
String? _url;
|
||||
String? _version;
|
||||
|
||||
UpdateVersionModel copyWith({
|
||||
num? createdAt,
|
||||
num? id,
|
||||
num? isUp,
|
||||
String? message,
|
||||
num? sel,
|
||||
String? source,
|
||||
String? type,
|
||||
num? updatedAt,
|
||||
String? url,
|
||||
String? version,
|
||||
}) =>
|
||||
UpdateVersionModel(
|
||||
createdAt: createdAt ?? _createdAt,
|
||||
id: id ?? _id,
|
||||
isUp: isUp ?? _isUp,
|
||||
message: message ?? _message,
|
||||
sel: sel ?? _sel,
|
||||
source: source ?? _source,
|
||||
type: type ?? _type,
|
||||
updatedAt: updatedAt ?? _updatedAt,
|
||||
url: url ?? _url,
|
||||
version: version ?? _version,
|
||||
);
|
||||
|
||||
num? get createdAt => _createdAt;
|
||||
|
||||
num? get id => _id;
|
||||
|
||||
num? get isUp => _isUp;
|
||||
|
||||
String? get message => _message;
|
||||
|
||||
num? get sel => _sel;
|
||||
|
||||
String? get source => _source;
|
||||
|
||||
String? get type => _type;
|
||||
|
||||
num? get updatedAt => _updatedAt;
|
||||
|
||||
String? get url => _url;
|
||||
|
||||
String? get version => _version;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['createdAt'] = _createdAt;
|
||||
map['id'] = _id;
|
||||
map['isUp'] = _isUp;
|
||||
map['message'] = _message;
|
||||
map['sel'] = _sel;
|
||||
map['source'] = _source;
|
||||
map['type'] = _type;
|
||||
map['updatedAt'] = _updatedAt;
|
||||
map['url'] = _url;
|
||||
map['version'] = _version;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +49,8 @@ class HomeViewModel extends BaseUIModel {
|
|||
|
||||
Future.delayed(const Duration(milliseconds: 700), () {
|
||||
_checkLogin();
|
||||
|
||||
_checkAppVersion();
|
||||
});
|
||||
|
||||
EventManager.addListener<CallStatusChangeEvent>(this, (event) {
|
||||
|
|
@ -88,6 +90,10 @@ class HomeViewModel extends BaseUIModel {
|
|||
yjPrint("is login $flag");
|
||||
}
|
||||
|
||||
_checkAppVersion() {
|
||||
AppManager.checkAppVersion();
|
||||
}
|
||||
|
||||
void setIndex(int index) {
|
||||
if (_currentIndex == index) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ import '../common/base/provider.dart';
|
|||
class OrderView extends BaseUI {
|
||||
@override
|
||||
Widget buildBody(BuildContext context) {
|
||||
return Container(
|
||||
child: Center(
|
||||
child: Text("Order"),
|
||||
),
|
||||
return const Center(
|
||||
child: Text("Order"),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cashier_reserve/common/encrypt/pwd.dart';
|
||||
import 'package:cashier_reserve/common/manager/app_manager.dart';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:cashier_reserve/common/request/request_manager.dart';
|
||||
import 'package:cashier_reserve/data_model/version/update_version_model.dart';
|
||||
|
||||
class VersionModel {
|
||||
static Future<UpdateVersionModel?> requestNewVersionInfo() async {
|
||||
final r = await RequestManager.get("/api/tbVersion/findBySource", params: {"source": "电话机"});
|
||||
if (r is Map) {
|
||||
return UpdateVersionModel.fromJson(r);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
import 'package:cashier_reserve/common/print/print.dart';
|
||||
import 'package:cashier_reserve/data_model/version/update_version_model.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:percent_indicator/percent_indicator.dart';
|
||||
|
||||
class UpdateVersionView extends StatefulWidget {
|
||||
final UpdateVersionModel versionModel;
|
||||
|
||||
const UpdateVersionView({super.key, required this.versionModel});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _UpdateVersionViewState();
|
||||
}
|
||||
}
|
||||
|
||||
class _UpdateVersionViewState extends State<UpdateVersionView> {
|
||||
DateTime? lastPopTime;
|
||||
|
||||
double progress = 0;
|
||||
String progressText = "0%";
|
||||
|
||||
bool isDownload = false;
|
||||
|
||||
// 用于控制下载任务取消的CancelToken
|
||||
CancelToken? _cancelToken;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cancelToken?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: (widget.versionModel.isUp ?? 0) != 0,
|
||||
onPopInvokedWithResult: (didPop, result) async {
|
||||
// 点击返回键的操作
|
||||
if (lastPopTime == null ||
|
||||
DateTime.now().difference(lastPopTime!) >
|
||||
const Duration(seconds: 2)) {
|
||||
lastPopTime = DateTime.now();
|
||||
// Utils.toast('再按一次退出', context);
|
||||
} else {
|
||||
lastPopTime = DateTime.now();
|
||||
// 退出app
|
||||
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.black.withOpacity(0.2),
|
||||
body: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
color: const Color(0x55000000),
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.fromLTRB(30, 30, 30, 30),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
width: 400,
|
||||
// height: 400,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"发现新版本",
|
||||
style:
|
||||
TextStyle(fontSize: 22, color: Color(0xff333333)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
widget.versionModel.message ?? "",
|
||||
style: const TextStyle(
|
||||
fontSize: 16, color: Color(0xff666666)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
isDownload
|
||||
? LinearPercentIndicator(
|
||||
padding: EdgeInsets.zero,
|
||||
animation: false,
|
||||
lineHeight: 20.0,
|
||||
// animationDuration: 2500,
|
||||
percent: progress,
|
||||
center: Text(progressText),
|
||||
// linearStrokeCap: LinearStrokeCap.roundAll,
|
||||
progressColor: Colors.green,
|
||||
)
|
||||
: Container(),
|
||||
isDownload
|
||||
? const SizedBox(
|
||||
height: 20,
|
||||
)
|
||||
: Container(),
|
||||
_buildActionViews(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildActionViews(BuildContext context) {
|
||||
bool isMustUpdate = widget.versionModel.isUp == 1;
|
||||
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
isMustUpdate
|
||||
? Container()
|
||||
: ElevatedButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.white),
|
||||
foregroundColor:
|
||||
WidgetStateProperty.all(const Color(0xff666666)),
|
||||
minimumSize: WidgetStateProperty.all(const Size(100, 40)),
|
||||
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
)),
|
||||
),
|
||||
child: const Text("跳过"),
|
||||
),
|
||||
isMustUpdate
|
||||
? Container()
|
||||
: const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
startDownload();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Colors.blue),
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white),
|
||||
minimumSize:
|
||||
WidgetStateProperty.all(Size(isMustUpdate ? 200 : 100, 40)),
|
||||
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
)),
|
||||
),
|
||||
child: const Text("立即更新"),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
startDownload() async {
|
||||
setState(() {
|
||||
isDownload = true;
|
||||
});
|
||||
|
||||
String fileUrl = widget.versionModel.url ?? "";
|
||||
if (fileUrl.isEmpty) {
|
||||
yjPrint("下载地址为空");
|
||||
return;
|
||||
}
|
||||
|
||||
_cancelToken?.cancel();
|
||||
|
||||
setState(() {
|
||||
progress = 0.0;
|
||||
progressText = "0.0%";
|
||||
});
|
||||
|
||||
yjPrint("fileUrl: $fileUrl");
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
String savePath = await getPhoneLocalPath();
|
||||
String appName = "file.apk";
|
||||
_cancelToken = CancelToken(); // 创建CancelToken对象
|
||||
await dio.download(
|
||||
fileUrl, "$savePath$appName", onReceiveProgress: (received, total) {
|
||||
if (total != -1) {
|
||||
///当前下载的百分比例
|
||||
double currentProgress = received / total;
|
||||
setState(() {
|
||||
progressText = "${(currentProgress * 100).toStringAsFixed(2)}%";
|
||||
progress = double.parse(currentProgress.toStringAsFixed(2));
|
||||
});
|
||||
yjPrint(progress);
|
||||
|
||||
_cancelToken = null;
|
||||
}
|
||||
}, cancelToken: _cancelToken);
|
||||
|
||||
yjPrint("文件下载成功");
|
||||
} catch (e) {
|
||||
yjPrint("文件下载失败:$e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getPhoneLocalPath() async {
|
||||
final directory = await getExternalStorageDirectory();
|
||||
return directory?.path ?? '';
|
||||
}
|
||||
}
|
||||
24
pubspec.lock
24
pubspec.lock
|
|
@ -418,6 +418,22 @@ packages:
|
|||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "8.1.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -783,6 +799,14 @@ packages:
|
|||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.9.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ dependencies:
|
|||
pointycastle: ^3.9.1
|
||||
url_launcher: ^6.3.1
|
||||
easy_refresh: ^3.4.0
|
||||
package_info_plus: ^8.1.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue