diff --git a/README.md b/README.md
index 105d86c..bb08a53 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,78 @@
-# problem_check_system
+# 项目名称:现场问题检查系统
-系统架构为MVVM + 仓库模式
+## 核心功能
-这个应用需要实现以下功能:
+本系统旨在为现场工作人员提供一个高效的问题记录与管理平台,支持离线操作和数据同步。
-离线登录系统
+1.1 在线/离线登录
+需求: 用户能够使用用户名和密码进行登录。如果设备曾成功登录过,即使在离线状态下也能进入应用。
-问题数据收集(描述、位置、图片等)
+技术实现思路:
-本地数据存储
+在线: 登录成功后,从服务器获取用户身份信息和Token。
-有网络时手动上传功能
+离线: 将登录凭证(如Token)安全地存储在本地数据库中,启动时优先检查本地凭证。如果凭证有效,直接进入主界面。
-技术栈
-Flutter SDK
+1.2 问题数据离线增删改查
+需求: 用户在离线状态下能完整地创建、编辑、删除和查询问题数据。
-GetX (状态管理、路由管理、依赖注入)
+技术实现思路:
-SQFlite (本地数据库)
+本地数据库: 使用 SQFlite 作为本地数据库。
-Image Picker (图片选择)
+数据结构: 设计清晰的数据库表结构,包含问题描述、图片路径、创建时间、状态(如“待上传”)等字段。
-Geolocator (位置信息)
+操作: 所有的增删改查操作都直接在本地数据库上进行。
-HTTP/Dio (网络请求)
+1.3 问题数据上传/下载
+需求: 在有网络连接时,系统能自动或手动将本地数据同步到服务器,并从服务器下载最新数据。
-# !/bin/bash
+技术实现思路:
-echo "开始清理..."
-flutter clean
+上传队列: 在本地数据库中新增一个“待上传”队列。当用户离线进行增删改操作时,将这些操作记录在队列中。
-echo "获取依赖..."
-flutter pub get
+智能同步: 当网络恢复时,按顺序处理上传队列中的任务。使用统一的 HTTP/Dio 拦截器处理身份验证和错误重试。
-echo "构建APK..."
-flutter build apk --release --target-platform android-arm64
+差异化下载: 从服务器下载数据时,只拉取自上次同步以来有更新的数据,避免全量下载。
-echo "构建完成!APK位置:build/app/outputs/flutter-apk/app-release.apk"
+2. 系统架构:MVVM + 仓库模式
+此架构能有效分离关注点,提高代码的可测试性和可维护性。
+
+模型 (Model): 负责数据管理。定义问题数据的实体类,如 Problem。
+
+视图模型 (ViewModel): 作为视图和模型之间的桥梁。
+
+负责业务逻辑、状态管理和数据处理。
+
+通过 GetX 管理 UI 状态,并与视图进行绑定。
+
+使用 GetX 的依赖注入(DI)管理 Repository 实例。
+
+视图 (View): 负责 UI 展示。
+
+使用 Flutter Widgets 构建界面。
+
+通过 GetX 提供的响应式组件(如 Obx),监听 ViewModel 中的状态变化并自动更新 UI。
+
+仓库 (Repository): 负责统一数据源(本地数据库和网络)。
+
+封装数据访问逻辑,向 ViewModel 提供统一的数据接口。
+
+根据网络状态,决定是从 SQFlite 获取数据还是从网络请求。
+
+3. 技术栈
+Flutter SDK: 跨平台应用开发框架。
+
+GetX:
+
+状态管理: 轻量高效,用于管理 UI 状态。
+
+路由管理: 简化页面跳转。
+
+依赖注入: 方便管理和提供单例服务(如 Repository)。
+
+SQFlite: 本地数据库,用于离线数据存储。
+
+Image Picker: 用于从图库或相机选择图片。
+
+HTTP/Dio: 网络请求库。推荐使用 Dio,因为它提供了更强大的拦截器、表单数据处理和错误处理功能。
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 8bc9705..399687d 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -2,9 +2,9 @@
-
+
+
@@ -16,6 +16,16 @@
android:label="现场问题检查"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/app/bindings/initial_binding.dart b/lib/app/bindings/initial_binding.dart
index 54dad48..c4b6468 100644
--- a/lib/app/bindings/initial_binding.dart
+++ b/lib/app/bindings/initial_binding.dart
@@ -8,6 +8,7 @@ import 'package:problem_check_system/data/repositories/file_repository.dart';
import 'package:problem_check_system/data/repositories/image_repository.dart';
import 'package:problem_check_system/data/repositories/image_repository_impl.dart';
import 'package:problem_check_system/data/repositories/problem_repository.dart';
+import 'package:problem_check_system/data/providers/upgrader_service.dart';
import 'package:uuid/uuid.dart';
class InitialBinding implements Bindings {
@@ -19,6 +20,7 @@ class InitialBinding implements Bindings {
void _registerCoreServices() {
/// 立即注册所有的适配器
+ Get.put(UpgraderService());
Get.put(GetStorage(), permanent: true);
Get.put(Uuid(), permanent: true);
Get.put(HttpProvider());
diff --git a/lib/data/providers/upgrader_service.dart b/lib/data/providers/upgrader_service.dart
new file mode 100644
index 0000000..dbbc56d
--- /dev/null
+++ b/lib/data/providers/upgrader_service.dart
@@ -0,0 +1,213 @@
+import 'dart:io';
+import 'package:dio/dio.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:open_file/open_file.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+class UpgraderService extends GetxService {
+ final Dio _dio = Dio();
+ final String _versionUrl =
+ 'http://xhota.anxincloud.cn/problem/version.json'; // 您的版本信息 JSON 地址
+
+ var isUpdateAvailable = false.obs;
+ var updateInfo = {}.obs;
+ var downloadProgress = '0'.obs;
+ var totalSize = '0'.obs;
+ var isDownloading = false.obs;
+
+ @override
+ void onInit() {
+ super.onInit();
+ checkForUpdate();
+ }
+
+ // 检查更新
+ Future checkForUpdate() async {
+ try {
+ // 获取当前应用版本信息
+ PackageInfo packageInfo = await PackageInfo.fromPlatform();
+ String currentVersion = packageInfo.version;
+
+ final response = await _dio.get(_versionUrl);
+ if (response.statusCode == 200) {
+ final latestVersion = response.data['version'];
+ if (latestVersion.compareTo(currentVersion) > 0) {
+ isUpdateAvailable.value = true;
+ updateInfo.value = response.data;
+ showUpdateDialog();
+ }
+ }
+ } catch (e) {
+ Get.log('检查更新失败: $e');
+ }
+ }
+
+ // 显示更新提示对话框
+ void showUpdateDialog() {
+ Get.dialog(
+ AlertDialog(
+ title: Text('发现新版本'),
+ content: Text(updateInfo['description'] ?? '有新的更新可用。'),
+ actions: [
+ TextButton(onPressed: () => Get.back(), child: Text('稍后')),
+ TextButton(
+ onPressed: () {
+ Get.back();
+ startDownload();
+ },
+ child: Text('立即更新'),
+ ),
+ ],
+ ),
+ barrierDismissible: false,
+ );
+ }
+
+ // 开始下载
+ Future startDownload() async {
+ isDownloading.value = true;
+ showDownloadProgressDialog();
+
+ try {
+ Directory? dir = await getExternalStorageDirectory();
+
+ if (dir == null) {
+ Get.back(); // 关闭进度对话框
+ Get.snackbar('错误', '无法获取外部存储目录。');
+ print('错误: getExternalStorageDirectory() 返回 null');
+ isDownloading.value = false;
+ return; // 提前退出
+ }
+
+ String savePath = '${dir.path}/app-release.apk';
+ print('--- 调试信息 ---');
+ print('目标下载路径: $savePath');
+ print('--- 调试信息 ---');
+
+ // 确保父目录存在
+ final file = File(savePath);
+ if (!await file.parent.exists()) {
+ await file.parent.create(recursive: true);
+ print('--- 调试信息 ---');
+ print('已尝试创建父目录: ${file.parent.path}');
+ print('--- 调试信息 ---');
+ }
+
+ await _dio.download(
+ updateInfo['url'],
+ savePath,
+ onReceiveProgress: (received, total) {
+ if (total != -1) {
+ downloadProgress.value = (received / 1024 / 1024).toStringAsFixed(
+ 2,
+ );
+ totalSize.value = (total / 1024 / 1024).toStringAsFixed(2);
+ // 在进度回调中也打印路径,确保一直有效
+ // print('下载进度 - 目标路径: $savePath');
+ }
+ },
+ options: Options(
+ receiveTimeout: const Duration(seconds: 30), // 增加超时时间
+ sendTimeout: const Duration(seconds: 30),
+ ),
+ );
+
+ isDownloading.value = false;
+ Get.back(); // 关闭下载进度对话框
+
+ // 再次验证文件是否存在
+ if (await file.exists()) {
+ final fileSize = await file.length();
+ Get.log('文件验证成功!路径: $savePath');
+ Get.log('文件大小: ${(fileSize / 1024 / 1024).toStringAsFixed(2)} MB');
+ installApk(savePath);
+ } else {
+ Get.snackbar('下载失败', '文件下载完毕但未找到,请联系管理员。');
+ Get.log('错误:文件下载完毕但未找到!');
+ }
+ } on DioException catch (e) {
+ // 使用 DioException 捕获更具体的 Dio 错误
+ isDownloading.value = false;
+ Get.back();
+ String errorMessage = '下载失败: 网络或服务器问题。';
+ if (e.type == DioExceptionType.badResponse) {
+ errorMessage = '下载失败: 服务器响应错误 (${e.response?.statusCode})';
+ Get.log('Dio响应错误: ${e.response?.data}');
+ } else if (e.type == DioExceptionType.connectionError) {
+ errorMessage = '下载失败: 连接错误,请检查网络。';
+ } else if (e.type == DioExceptionType.unknown) {
+ // 可能是文件系统错误、权限错误等
+ errorMessage = '下载失败: 未知错误。请检查存储权限或设备空间。';
+ Get.log('Dio未知错误: $e');
+ }
+ Get.snackbar('下载失败', errorMessage);
+ Get.log('下载失败 (DioException): $e');
+ } catch (e) {
+ isDownloading.value = false;
+ Get.back();
+ Get.snackbar('下载失败', '发生未知错误。');
+ Get.log('下载失败 (通用异常): $e');
+ }
+ }
+
+ // 显示下载进度对话框
+ void showDownloadProgressDialog() {
+ Get.dialog(
+ AlertDialog(
+ title: Text('正在下载更新...'),
+ content: Obx(
+ () => Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ LinearProgressIndicator(
+ value: totalSize.value == '0'
+ ? null
+ : double.parse(downloadProgress.value) /
+ double.parse(totalSize.value),
+ ),
+ SizedBox(height: 16),
+ Text('${downloadProgress.value} MB / ${totalSize.value} MB'),
+ ],
+ ),
+ ),
+ ),
+ barrierDismissible: false,
+ );
+ }
+
+ // 安装 APK
+ Future installApk(String path) async {
+ // 检查安装权限
+ var status = await Permission.requestInstallPackages.status;
+ if (status.isGranted) {
+ // 权限已授予,直接安装
+ _openApkFile(path);
+ } else {
+ // 权限未授予,发起请求
+ // 这会打开系统设置页面,让用户手动授权
+ status = await Permission.requestInstallPackages.request();
+ if (status.isGranted) {
+ _openApkFile(path);
+ } else {
+ // 如果用户拒绝了权限,给出提示
+ Get.snackbar(
+ '权限被拒绝',
+ '需要授权才能安装更新。请在系统设置中为本应用开启“安装未知应用”的权限。',
+ duration: Duration(seconds: 5),
+ );
+ }
+ }
+ }
+
+ // 抽离出打开文件的逻辑
+ Future _openApkFile(String path) async {
+ final result = await OpenFile.open(path);
+ print('OpenFile result: ${result.type}, message: ${result.message}');
+ if (result.type != ResultType.done) {
+ Get.snackbar('安装失败', '无法启动安装程序: ${result.message}');
+ }
+ }
+}
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index 64a0ece..86be7eb 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -7,9 +7,17 @@
#include "generated_plugin_registrant.h"
#include
+#include
+#include
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
+ g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
+ fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
+ open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
+ 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/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index 2db3c22..c842924 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -4,6 +4,8 @@
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
+ open_file_linux
+ url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index e2ff0cb..ba06083 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -7,12 +7,20 @@ import Foundation
import connectivity_plus
import file_selector_macos
+import open_file_mac
+import package_info_plus
import path_provider_foundation
+import shared_preferences_foundation
import sqflite_darwin
+import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
+ OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
+ FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
+ SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
diff --git a/pubspec.lock b/pubspec.lock
index 12d8278..ebc9daf 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -169,6 +169,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.6"
+ csslib:
+ dependency: transitive
+ description:
+ name: csslib
+ sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.2"
dart_style:
dependency: transitive
description:
@@ -389,6 +397,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
+ html:
+ dependency: transitive
+ description:
+ name: html
+ sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.15.6"
http:
dependency: transitive
description:
@@ -589,6 +605,78 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.5.0"
+ open_file:
+ dependency: "direct main"
+ description:
+ name: open_file
+ sha256: d17e2bddf5b278cb2ae18393d0496aa4f162142ba97d1a9e0c30d476adf99c0e
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.5.10"
+ open_file_android:
+ dependency: transitive
+ description:
+ name: open_file_android
+ sha256: "58141fcaece2f453a9684509a7275f231ac0e3d6ceb9a5e6de310a7dff9084aa"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.6"
+ open_file_ios:
+ dependency: transitive
+ description:
+ name: open_file_ios
+ sha256: "02996f01e5f6863832068e97f8f3a5ef9b613516db6897f373b43b79849e4d07"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ open_file_linux:
+ dependency: transitive
+ description:
+ name: open_file_linux
+ sha256: d189f799eecbb139c97f8bc7d303f9e720954fa4e0fa1b0b7294767e5f2d7550
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.0.5"
+ open_file_mac:
+ dependency: transitive
+ description:
+ name: open_file_mac
+ sha256: "1440b1e37ceb0642208cfeb2c659c6cda27b25187a90635c9d1acb7d0584d324"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ open_file_platform_interface:
+ dependency: transitive
+ description:
+ name: open_file_platform_interface
+ sha256: "101b424ca359632699a7e1213e83d025722ab668b9fd1412338221bf9b0e5757"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ open_file_web:
+ dependency: transitive
+ description:
+ name: open_file_web
+ sha256: e3dbc9584856283dcb30aef5720558b90f88036360bd078e494ab80a80130c4f
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.0.4"
+ open_file_windows:
+ dependency: transitive
+ description:
+ name: open_file_windows
+ sha256: d26c31ddf935a94a1a3aa43a23f4fff8a5ff4eea395fe7a8cb819cf55431c875
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.0.3"
+ os_detect:
+ dependency: transitive
+ description:
+ name: os_detect
+ sha256: "7d87c0dd98c6faf110d5aa498e9a6df02ffce4bb78cc9cfc8ad02929be9bb71f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.3"
package_config:
dependency: transitive
description:
@@ -597,6 +685,22 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.0"
+ package_info_plus:
+ dependency: "direct main"
+ description:
+ name: package_info_plus
+ sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "9.0.0"
+ package_info_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: package_info_plus_platform_interface
+ sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.1"
path:
dependency: "direct main"
description:
@@ -773,6 +877,62 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.5.0"
+ shared_preferences:
+ dependency: transitive
+ description:
+ name: shared_preferences
+ sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.5.3"
+ shared_preferences_android:
+ dependency: transitive
+ description:
+ name: shared_preferences_android
+ sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.13"
+ shared_preferences_foundation:
+ dependency: transitive
+ description:
+ name: shared_preferences_foundation
+ sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.5.4"
+ shared_preferences_linux:
+ dependency: transitive
+ description:
+ name: shared_preferences_linux
+ sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_platform_interface:
+ dependency: transitive
+ description:
+ name: shared_preferences_platform_interface
+ sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_web:
+ dependency: transitive
+ description:
+ name: shared_preferences_web
+ sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.3"
+ shared_preferences_windows:
+ dependency: transitive
+ description:
+ name: shared_preferences_windows
+ sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
shelf:
dependency: transitive
description:
@@ -946,6 +1106,78 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
+ upgrader:
+ dependency: "direct main"
+ description:
+ name: upgrader
+ sha256: a28de64108db70f77e5eacf8b87c1bdfaf9374ece9cab26f9aeac26ac3403eff
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "12.1.0"
+ url_launcher:
+ dependency: transitive
+ description:
+ name: url_launcher
+ sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.2"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.20"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.4"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.3"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.3.2"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.4"
uuid:
dependency: "direct main"
description:
@@ -962,6 +1194,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
+ version:
+ dependency: transitive
+ description:
+ name: version
+ sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.2"
vm_service:
dependency: transitive
description:
@@ -1002,6 +1242,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.14.0"
xdg_directories:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 34137a8..f35899b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,7 @@
name: problem_check_system
description: "A new Flutter project."
publish_to: "none"
-version: 0.1.0
+version: 1.0.0
environment:
sdk: ^3.8.1
@@ -22,12 +22,15 @@ dependencies:
image_picker: ^1.1.2
intl: ^0.20.2
json_annotation: ^4.9.0
+ open_file: ^3.5.10
+ package_info_plus: ^9.0.0
path: ^1.9.1
path_provider: ^2.1.5
permission_handler: ^12.0.1
pretty_dio_logger: ^1.4.0
sqflite: ^2.4.2
tdesign_flutter: ^0.2.4
+ upgrader: ^12.1.0
uuid: ^4.5.1
dev_dependencies:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 84f9bcc..dbf8289 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
@@ -17,4 +18,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FileSelectorWindows"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index bd04dca..c22844a 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
file_selector_windows
permission_handler_windows
+ url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST