feat:切换flutter版本

This commit is contained in:
dzc committed 2025-03-16 18:01:05 +08:00
1 parent ee761ccc48
commit 72443f7abf
32 files changed
+536 -375

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
{
"flutter": "3.27.4"
}
+3
View File
@@ -43,3 +43,6 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
# FVM Version Cache
.fvm/
+26
View File
@@ -0,0 +1,26 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "pj_supermarket_cloud",
"request": "launch",
"type": "dart"
},
{
"name": "pj_supermarket_cloud (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "pj_supermarket_cloud (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"dart.flutterSdkPath": ".fvm/versions/3.27.4"
}
+9 -3
View File
@@ -22,13 +22,19 @@
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:label="智慧食堂"
android:largeHeap="true"
android:requestLegacyExternalStorage="true">
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
@@ -41,8 +47,8 @@
<activity
android:name="io.flutter.plugins.facediscern.ui.FaceDiscern"
android:exported="false"
android:hardwareAccelerated="false"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.NoActionBar" />
@@ -5,8 +5,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
@@ -76,15 +74,10 @@ public class FlutterFaceDiscernPlugin implements FlutterPlugin, MethodChannel.Me
switch (method) {
case "jumpFaceDiscern":
try {
// Intent intent = new Intent(context, FaceDiscern.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// context.startActivity(intent);
Intent intent = new Intent(context, FaceDiscern.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
new Handler(Looper.getMainLooper()).post(() -> context.startActivity(intent));
context.startActivity(intent);
result.success(true);
} catch (Exception e) {
result.success(false);
@@ -4,10 +4,7 @@ import android.Manifest;
import android.content.Intent;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
@@ -18,9 +15,9 @@ import androidx.core.app.ActivityCompat;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import com.example.pj_supermarket_cloud.MainActivity;
import com.example.pj_supermarket_cloud.R;
import com.example.pj_supermarket_cloud.databinding.ActivityFaceDiscernBinding;
import com.example.pj_supermarket_cloud.tool.FlutterRouterManager;
import io.flutter.Log;
import io.flutter.embedding.android.FlutterActivity;
@@ -96,12 +93,6 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob
initRgbCamera();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "相机触发onNewIntent");
}
@Override
protected void onDestroy() {
super.onDestroy();
@@ -133,10 +124,13 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob
if (Objects.nonNull(channel)) {
channel.invokeMethod("faceDiscernPageInit", null);
}
if (rgbCameraHelper != null) {
rgbCameraHelper.resumePreview();
}
scheduler.schedule(() -> {
try {
if (rgbCameraHelper != null) {
rgbCameraHelper.resumePreview();
if (viewModel != null) {
viewModel.stop();
previewLock = false;
Log.i(TAG, "相机开始识别");
}
@@ -155,26 +149,33 @@ public class FaceDiscern extends BaseActivity implements ViewTreeObserver.OnGlob
}
}
// 以前的方式
// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// 推荐的方式
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// 手机返回按钮
@Override
public void onBackPressed() {
Log.e(TAG, "相机onBackPressed");
if (rgbCameraHelper != null) {
rgbCameraHelper.stop();
}
if (viewModel != null) {
viewModel.stop();
}
binding.dualCameraFaceRectView.clearFaceInfo();
previewLock = true;
MethodChannel channel = FlutterFaceDiscernPlugin.staticChannel;
if (Objects.nonNull(channel)) {
channel.invokeMethod("faceDiscernBack", null);
}
// FlutterRouterManager loadEngine = new FlutterRouterManager("/load", "login_engine", this);
// loadEngine.push();
// loadEngine.destroy();
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(this.getPackageName(), this.getPackageName() + ".MainActivity");
this.startActivity(intent);
}
@@ -20,10 +20,8 @@ import com.arcsoft.face.LivenessInfo;
import com.arcsoft.face.LivenessParam;
import com.arcsoft.face.enums.DetectFaceOrientPriority;
import com.arcsoft.face.enums.DetectMode;
import com.example.pj_supermarket_cloud.MainActivity;
import com.google.gson.Gson;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugins.facediscern.tool.camera.DualCameraHelper;
import io.flutter.plugins.facediscern.tool.camera.config.PreviewConfig;
import io.flutter.plugins.facediscern.tool.face.constants.FaceBrodConstant;
@@ -293,15 +291,17 @@ public class FaceDiscernViewModel extends ViewModel implements RecognizeCallback
if (flutterFaceCallbackIntent == null) {
flutterFaceCallbackIntent = new Intent(FaceBrodConstant.FACE_GLOBAL_INTENT);
}
flutterFaceCallbackIntent.putExtra("json", new Gson().toJson(faceDiscern));
Log.i(TAG, "人脸识别成功json:" + new Gson().toJson(faceDiscern));
flutterFaceCallbackIntent.putExtra("json", new Gson().toJson(faceDiscern));
context.sendBroadcast(flutterFaceCallbackIntent);
faceDiscern = null;
if (context instanceof Activity) {
Thread.sleep(500);
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
String packageName = context.getPackageName();
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(packageName, packageName + ".MainActivity");
context.startActivity(intent);
context.sendBroadcast(flutterFaceCallbackIntent);
faceDiscern = null;
}
} catch (Exception e) {
Log.e(TAG, "提示文字变更的回调,错误error:" + e.getMessage(), e);
@@ -17,4 +17,4 @@ class MainActivity : FlutterActivity() {
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
}
@@ -0,0 +1,75 @@
package com.example.pj_supermarket_cloud.tool
import android.app.Activity
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterActivityLaunchConfigs
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.dart.DartExecutor
class FlutterRouterManager(val targetRoute: String, val mEngineId: String, val mContext: Activity) {
var mEngine: FlutterEngine? = null
init {
createCachedEngine()
}
companion object {
/**
* 获取缓存中的 Flutter引擎
*/
@JvmStatic
fun getEngineCacheInstance(engineId: String): FlutterEngine? {
return FlutterEngineCache.getInstance().get(engineId)
}
}
/**
* 1、创建Flutter引擎
* 2、将初始命名路由,修改为目标页面路由
* 3、缓存Flutter引擎
*/
fun createCachedEngine(): FlutterEngine {
val flutterEngine = FlutterEngine(mContext) // 创建Flutter引擎
// 将初始命名路由,修改为目标页面路由
flutterEngine.navigationChannel.setInitialRoute(targetRoute)
// 这一步,是在执行相关Dart文件入口的 main函数,将Flutter页面渲染出结果
// 原生端获取结果,进行最终渲染上屏
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
// 将加载好的引擎,存储起来
FlutterEngineCache.getInstance().put(mEngineId, flutterEngine)
mEngine = flutterEngine
return flutterEngine
}
/**
* 根据引擎ID,前往指定的Flutter页面
*/
fun push() {
// 使用缓存好的引擎(推荐)
mContext.startActivity(
FlutterActivity
.withCachedEngine(mEngineId)
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.build(mContext)
)
}
/**
* 销毁当前Flutter引擎
*/
fun destroy() {
mEngine?.destroy()
}
}
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 是否在初始化时自动显示副屏 -->
<bool name="autoShowSubScreenWhenInit">true</bool>
</resources>
+9 -9
View File
@@ -21,15 +21,6 @@ class RoutePages {
Get.lazyPut(() => PanelController());
}),
),
GetPage(
name: RouteNames.supermarketProduct,
page: () => const SupermarketOrderPage(),
binding: BindingsBuilder(() {
Get.lazyPut(() => SelectPayTypeDialogController());
Get.lazyPut(() => PanelController());
Get.lazyPut(() => SupermarketOrderController());
}),
),
GetPage(
name: RouteNames.canteenProduct,
page: () => const CanteenProductPage(),
@@ -39,6 +30,15 @@ class RoutePages {
Get.lazyPut(() => PanelController());
}),
),
GetPage(
name: RouteNames.supermarketProduct,
page: () => const SupermarketOrderPage(),
binding: BindingsBuilder(() {
Get.lazyPut(() => SelectPayTypeDialogController());
Get.lazyPut(() => PanelController());
Get.lazyPut(() => SupermarketOrderController());
}),
),
GetPage(
name: RouteNames.takeFood,
page: () => const TakeFoodPage(),
@@ -14,28 +14,28 @@ class ClassifyEntity extends Equatable {
int? id;
/// 服务端唯一标识
String serviceUniqueCode;
final String serviceUniqueCode;
/// 平台类型
SysType sysType;
final SysType sysType;
/// 分类名
String name;
final String name;
/// 用餐类型,早餐、中餐、晚餐
String categoryType;
final String categoryType;
/// 排序 倒序排列
int sort;
final int sort;
/// 创建时间
DateTime createTime;
final DateTime createTime;
/// 同步时间
DateTime updateTime;
final DateTime updateTime;
/// 是否删除
bool delFlag;
final bool delFlag;
ClassifyEntity({
this.id,
@@ -91,8 +91,6 @@ abstract class AppSettingTool {
}
static Future<void> setSysSetting(SysSetting sysInfo) async {
final globalSysInfo = await getSysSetting();
if (globalSysInfo == sysInfo) return;
await _setSetting(sysJson: sysInfo);
}
@@ -19,6 +19,7 @@ class AppControl extends GetxController {
/// mq
StreamSubscription? mqListen;
EventBus mqUpdateEventBus = EventBus();
/// 数据库
@@ -34,7 +35,7 @@ class AppControl extends GetxController {
serialCardManage.close();
srialSteelyardManage.close();
AppNetworkTool.closeListenNetwork();
// TtsManage.dispose();
TtsManage.dispose();
}
Future<void> initAsync() async {
@@ -43,8 +44,8 @@ class AppControl extends GetxController {
serialCardManage = SerialCardManage();
srialSteelyardManage = SerialSteelyardManage();
AppNetworkTool.listenNetwork();
// await AppFileTool.backupSqlFile();
// await TtsManage.initialize();
await AppFileTool.backupSqlFile();
await TtsManage.initialize();
Get.offAllNamed(RouteNames.login);
}
}
+6 -5
View File
@@ -8,25 +8,26 @@ abstract class SyncConfigTool {
static const _tag = "sync配置工具";
// 自动同步设备信息导本地缓存
static Future<void> autoSyncSysInfo() async {
static Future<SysSetting?> autoSyncSysInfo() async {
final login = await AppUserTool.isLogin();
if (!login) return;
if (!login) return null;
final sysSetting = await AppSettingTool.getSysSetting();
logger.i("|$_tag|开始同步设备信息 sysInfo:|${json.encode(sysSetting)}|");
if (ObjectUtil.isEmpty(sysSetting)) return;
if (ObjectUtil.isEmpty(sysSetting.serviceId)) return;
if (ObjectUtil.isEmpty(sysSetting)) return null;
if (ObjectUtil.isEmpty(sysSetting.serviceId)) return null;
final serviceId = sysSetting.serviceId;
final pa = {"id": serviceId};
final data = await HardApi.get(pa);
if (data == null) {
logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;");
return;
return null;
}
// 基本信息
await AppSettingTool.updateSysInfoByService(data);
// 人脸sdk
await autoSyncFaceSdk(detail: data, sysInfo: sysSetting);
logger.i("|$_tag|结束同步设备信息 sysInfo:|${json.encode(sysSetting)}|");
return sysSetting;
}
// 自动同步设备信息导本地缓存-同步人脸sdk
+6 -38
View File
@@ -1,5 +1,6 @@
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:common_utils/common_utils.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
@@ -15,31 +16,11 @@ Widget appNetworkImg(
double imgHeight = 60,
BoxFit fit = BoxFit.cover,
}) {
return Image.network(
src,
width: imgWidth,
height: imgHeight,
fit: fit,
loadingBuilder:
(BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: SizedBox(
width: imgHeight,
height: imgHeight,
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
(loadingProgress.expectedTotalBytes ?? 1)
: null,
),
),
);
}
},
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
return CachedNetworkImage(
imageUrl: AppNetworkTool.ossImage(src),
placeholder: (context, url) =>
CircularProgressIndicator().width(50.w).height(50.w),
errorWidget: (context, url, error) {
final theme = FTheme.of(context);
return FIcon(
FAssets.icons.globeLock,
@@ -48,19 +29,6 @@ Widget appNetworkImg(
).width(imgWidth * 0.5).height(imgHeight * 0.5);
},
);
// return CachedNetworkImage(
// imageUrl: AppNetworkTool.ossImage(src),
// placeholder: (context, url) =>
// CircularProgressIndicator().width(50.w).height(50.w),
// errorWidget: (context, url, error) {
// final theme = FTheme.of(context);
// return FIcon(
// FAssets.icons.globeLock,
// color: theme.colorScheme.error,
// size: theme.typography.base.fontSize,
// ).width(imgWidth * 0.5).height(imgHeight * 0.5);
// },
// );
}
Widget appFileImg(
@@ -14,9 +14,6 @@ mixin OrderMixin {
final appController = Get.find<AppControl>();
// 路由变化
StreamSubscription<GlobalRouter>? routerBus;
/// **************** start 需要重制 start ****************
// 时间类型
@@ -57,7 +54,7 @@ mixin OrderMixin {
);
// 当前的tab
RxInt currentTabIndex = RxInt(0);
int currentTabIndex = 0;
// 购买用户
Rxn<ServiceUser?> payUser = Rxn<ServiceUser>(null);
@@ -80,11 +77,12 @@ mixin OrderMixin {
// 点击分类tab
Future<void> doTab(int i) async {
if (currentTabIndex == i) return;
EasyLoading.show(
status: '切换中...',
maskType: EasyLoadingMaskType.black,
);
currentTabIndex.value = i;
currentTabIndex = i;
if (i <= classifyList.length - 1) {
final current = classifyList[i];
await getProduct(classifyCode: current.serviceUniqueCode);
@@ -113,12 +111,11 @@ mixin OrderMixin {
),
);
classifyList.value = list;
classifyList.refresh();
}
// 获取商品
Future<void> getProduct({
String classifyCode = "-1",
}) async {
Future<void> getProduct({String classifyCode = "-1"}) async {
final list = await appController.dataBase.getProductDao.getAll(
classifyCode,
hourType.value.code,
@@ -401,9 +398,7 @@ mixin OrderMixin {
/// **************** start 副屏幕相关 start ****************
void putOffSendSubScreen({
int seconds = 5,
}) {
void putOffSendSubScreen({int seconds = 5}) {
if (putOffSendSubScreenDelayed != null) {
sendSubScreen();
putOffSendSubScreenDelayed = null;
@@ -432,18 +427,6 @@ mixin OrderMixin {
/// **************** end 副屏幕相关 end ****************
/// **************** start 路由变化相关 start ****************
listenRouter() {
routerBus = GlobalRouteObserver.globalRouteObserverBus
.on<GlobalRouter>()
.listen((event) {
if (event.action == RouterActionType.didPop &&
event.name == RouteNames.faceDiscern) {}
});
}
/// **************** end 路由变化相关 end ****************
// 生成安卓唯一的code
Future<String> _getUniqueCode() async {
String code = "";
@@ -1,3 +1,5 @@
import 'dart:ffi';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
@@ -148,3 +150,37 @@ Widget orderSelectPanel(
},
);
}
Widget orderRowClassify(
BuildContext context, {
required List<ClassifyEntity> classifyList,
required Function(int) onChange,
int currentTabIndex = 0,
}) {
final theme = FTheme.of(context);
return classifyList
.map((v) {
final target = classifyList[currentTabIndex];
final active = target.id == v.id;
return FButton(
style: active ? FButtonStyle.primary : FButtonStyle.secondary,
label: Text(
v.name,
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: theme.typography.xl.copyWith(
color: active
? theme.colorScheme.secondary
: theme.colorScheme.primary,
),
).center().width(120.w),
onPress: () {
final index = classifyList.indexWhere((i) => i.id == v.id);
onChange(index);
},
);
})
.toList()
.toRowSpace(space: 20.w);
}
@@ -12,6 +12,8 @@ import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class SelectPayTypeDialogController extends GetxController {
SelectPayTypeDialogController();
/// **************** start 回调函数 start ****************
// |开始识别|的回调
@@ -114,16 +116,16 @@ class SelectPayTypeDialogController extends GetxController {
}
// |开始识别|点击
doRecognition() {
Future<void> doRecognition() async {
switch (orderPayDisplayType.value) {
case OrderPayDisplayType.qrCode:
_dispatchQrCode();
await _dispatchQrCode();
break;
case OrderPayDisplayType.walletCard:
_dispatchWalletCard();
await _dispatchWalletCard();
break;
case OrderPayDisplayType.face:
_dispatchFace();
await _dispatchFace();
break;
default:
}
@@ -143,7 +145,7 @@ class SelectPayTypeDialogController extends GetxController {
globalQrCode,
);
_closeStatus();
Navigator.of(Get.context!, rootNavigator: true).pop();
Navigator.of(Get.context!).pop();
}
// |取消|点击
@@ -151,18 +153,18 @@ class SelectPayTypeDialogController extends GetxController {
if (isRecognition.value) {
final flag = await appMessageDialog(Get.context!, "是否取消识别");
if (!flag) return;
Navigator.of(Get.context!, rootNavigator: true).pop();
Navigator.of(Get.context!).pop();
return;
}
_closeStatus();
onCancel?.call();
Navigator.of(Get.context!, rootNavigator: true).pop();
Navigator.of(Get.context!).pop();
}
// **************************************************************************
// 二维码识别 start
// **************************************************************************
void _dispatchQrCode() async {
Future<void> _dispatchQrCode() async {
try {
if (isRecognition.value) {
Toast.error(msg: "正在识别中,请勿重复点击");
@@ -229,7 +231,7 @@ class SelectPayTypeDialogController extends GetxController {
// **************************************************************************
// 饭卡识别 start
// **************************************************************************
void _dispatchWalletCard() async {
Future<void> _dispatchWalletCard() async {
if (isRecognition.value) {
Toast.error(msg: "正在识别中,请勿重复点击");
return;
@@ -302,9 +304,8 @@ class SelectPayTypeDialogController extends GetxController {
// **************************************************************************
// 人脸支付 start
// **************************************************************************
void _dispatchFace() async {
Future<void> _dispatchFace() async {
try {
EasyLoading.dismiss();
EasyLoading.show(
status: '人脸识别准备中...',
maskType: EasyLoadingMaskType.black,
@@ -312,13 +313,15 @@ class SelectPayTypeDialogController extends GetxController {
final faceDao = app.dataBase.getFaceDao;
final databaseFaceCount = await faceDao.findCount("-1");
if (databaseFaceCount == null || databaseFaceCount == 0) {
Toast.error(msg: "人脸数据库为空,请前往'设置'->'人脸管理'点击同步人脸");
throw Error();
String msg = "人脸数据库为空,请前往'设置'->'人脸管理'点击同步人脸";
Toast.error(msg: msg);
throw Exception(msg);
}
final isActive = await AppFaceTool.isActiveSdk();
if (!isActive) {
Toast.error(msg: "请检查激人脸sdk激活码");
throw Error();
String msg = "请检查激人脸sdk激活码";
Toast.error(msg: msg);
throw Exception(msg);
}
final faceCount = await FaceDiscernPlugs.getFaceCount();
if (faceCount == 0) {
@@ -326,8 +329,9 @@ class SelectPayTypeDialogController extends GetxController {
}
final isJump = await AppFaceTool.jumpFacePage();
if (!isJump) {
Toast.error(msg: "跳转到人脸检测页面失败");
throw Error();
String msg = "跳转到人脸检测页面失败";
Toast.error(msg: msg);
throw Exception(msg);
}
faceDiscernListen = FaceDiscernPlugs.faceStream.listen((event) {
if (event == null) return;
@@ -342,6 +346,7 @@ class SelectPayTypeDialogController extends GetxController {
SubScreenPlugin.doubleScreenShow();
});
} catch (e) {
logger.e("|$_tag|跳转人脸识别页面,意外的错误error:|$e|");
EasyLoading.dismiss();
}
}
@@ -418,12 +423,11 @@ class SelectPayTypeDialogController extends GetxController {
}
Future<void> selectPayTypeDialog() async {
final context = Get.context!;
final payTypeC = Get.find<SelectPayTypeDialogController>();
payTypeC.initPayType();
final theme = FTheme.of(context);
final width = context.width;
final height = context.height;
final theme = FTheme.of(Get.context!);
final width = Get.context!.width;
final height = Get.context!.height;
return showDialog(
context: Get.context!,
barrierDismissible: false,
@@ -467,14 +471,8 @@ Future<void> selectPayTypeDialog() async {
Obx(
() => Visibility(
visible: payTypeC.payUser.value == null,
replacement: selectPayTypeUser(
context,
payTypeC.payUser.value,
),
child: selectPayTypeHint(
context,
payTypeC.orderPayDisplayType.value,
),
replacement: selectPayTypeUser(payTypeC.payUser.value),
child: selectPayTypeHint(payTypeC.orderPayDisplayType.value),
),
).center().expanded(),
].toColumn().width(width * 0.5).height(height * 0.6),
@@ -518,8 +516,8 @@ Future<void> selectPayTypeDialog() async {
);
}
Widget selectPayTypeUser(BuildContext context, ServiceUser? user) {
final theme = FTheme.of(context);
Widget selectPayTypeUser(ServiceUser? user) {
final theme = FTheme.of(Get.context!);
if (user == null) return const SizedBox.shrink();
final isFree = user.walletIsFreeze ?? true;
final textStyle = theme.typography.xl;
@@ -545,7 +543,7 @@ Widget selectPayTypeUser(BuildContext context, ServiceUser? user) {
style: titleTheme,
prefixIcon: FIcon(FAssets.icons.badgeDollarSign),
title: Text('余额', style: textStyle),
details: appPrice(context, user.walletBalance),
details: appPrice(Get.context!, user.walletBalance),
),
FTile(
style: titleTheme,
@@ -564,8 +562,8 @@ Widget selectPayTypeUser(BuildContext context, ServiceUser? user) {
.height(double.infinity);
}
Widget selectPayTypeHint(BuildContext context, OrderPayDisplayType? type) {
final theme = FTheme.of(context);
Widget selectPayTypeHint(OrderPayDisplayType? type) {
final theme = FTheme.of(Get.context!);
if (type == null) return const SizedBox.shrink();
const baseMsg = "请点击开始识别按钮";
String msg = "";
+15 -14
View File
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
@@ -8,10 +9,8 @@ import 'package:pj_supermarket_cloud/app.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import 'package:pj_supermarket_cloud/sub_screen/page/index.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
await checkSubScreen();
void main() {
checkSubScreen();
}
Future<void> checkSubScreen() async {
@@ -19,19 +18,21 @@ Future<void> checkSubScreen() async {
case "/":
final appTheme = Get.put(AppThemeControl());
runApp(MainApp());
final app = Get.put(AppControl());
await app.initAsync();
await appTheme.initAsync();
await Future.microtask(() async {
final app = Get.put(AppControl());
await app.initAsync();
await appTheme.initAsync();
});
break;
case "subMain":
await Future(() async {
bool isMultipleScreen = await SubScreenPlugin.isMultipleScreen;
bool isOverlay = await SubScreenPlugin.checkOverlayPermission;
if (isMultipleScreen && isOverlay) {
SubScreenPlugin.doubleScreenShow();
}
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
bool isMultipleScreen = await SubScreenPlugin.isMultipleScreen;
bool isOverlay = await SubScreenPlugin.checkOverlayPermission;
if (isMultipleScreen && isOverlay) {
runApp(SubAppPage());
});
SubScreenPlugin.doubleScreenShow();
}
break;
}
}
+29 -49
View File
@@ -1,11 +1,10 @@
import 'dart:async';
import 'package:common_utils/common_utils.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart';
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:forui/forui.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class CanteenProductController extends GetxController with OrderMixin {
@@ -13,9 +12,7 @@ class CanteenProductController extends GetxController with OrderMixin {
static const _tag = "食堂购买页面";
final app = Get.find<AppControl>();
StreamSubscription? mqUpdateListen;
final appC = Get.find<AppControl>();
final hourTypeC = FRadioSelectGroupController<String>(
value: ProductHourType.MORNING.code,
@@ -27,42 +24,48 @@ class CanteenProductController extends GetxController with OrderMixin {
update(["canteen_product"]);
}
void onTap() {}
@override
void onInit() async {
super.onInit();
EasyLoading.dismiss();
await _initState();
}
@override
void onReady() {
super.onReady();
_initData();
}
@override
void onClose() {
super.onClose();
SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubBack.name);
// 读卡器
appC.serialCardManage.readerClose();
appC.serialCardManage.close();
hourTypeC.dispose();
}
Future<void> _initState() async {
EasyLoading.show(
status: '初始化资源...',
maskType: EasyLoadingMaskType.black,
);
appSetting = await AppSettingTool.getSysSetting();
// 打开副屏
SubScreenPlugin.doubleScreenShow();
SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubPage.name);
/// **************** start 组件初始化 start ****************
// 组件初始化
hourType.value = appSetting.hourType ?? ProductHourType.MORNING;
hourTypeC.value = {hourType.value.code};
sysType = SysType.CANTEEN;
_listenPayTypeSelectCallback();
/// **************** end 组件初始化 end ****************
/// **************** start 获取分类和商品 start ****************
// 获取分类和商品
await getClassify();
await getProduct();
/// **************** end 获取分类和商品 end ****************
// 清空购物车
await _clearShopCard();
EasyLoading.dismiss();
// 监听时间段选择
hourTypeC.addValueListener((v) async {
final currentHourType = ProductHourType.values.fromCode(
v.first,
@@ -84,32 +87,13 @@ class CanteenProductController extends GetxController with OrderMixin {
});
}
@override
void onReady() {
super.onReady();
_initData();
}
@override
void onClose() {
super.onClose();
SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubBack.name);
// 读卡器
app.serialCardManage.readerClose();
app.serialCardManage.close();
// 路由监听
routerBus?.cancel();
mqUpdateListen?.cancel();
hourTypeC.dispose();
}
// |下单|点击购买
Future<void> doPay() async {
final validShopCar = _validateShopCar();
if (!validShopCar) return;
// 创建本地订单
await createSqlOrder();
await selectPayTypeDialog();
selectPayTypeDialog();
}
// |下单|点击取消下单
@@ -131,7 +115,6 @@ class CanteenProductController extends GetxController with OrderMixin {
return e.productServiceUniqueCode == current.productServiceUniqueCode;
});
}
shopCardList.refresh();
computedTotalPrice();
await _computedAmountMealPrice();
sendSubScreen();
@@ -162,7 +145,6 @@ class CanteenProductController extends GetxController with OrderMixin {
target.productNumber,
);
}
shopCardList.refresh();
computedTotalPrice();
await _computedAmountMealPrice();
sendSubScreen();
@@ -194,7 +176,6 @@ class CanteenProductController extends GetxController with OrderMixin {
this.orderPayDisplayType.value = orderPayDisplayType;
this.globalQrCode = qrCode;
payUser.value = user;
payUser.refresh();
final validPayUser = _validatePayUser();
if (!validPayUser) return;
final validShopCar = _validateShopCar();
@@ -265,9 +246,8 @@ class CanteenProductController extends GetxController with OrderMixin {
// 获取默认商品
Future<void> _getDefaultProduct() async {
final appSetting = await AppSettingTool.getSysSetting();
final sysType = appSetting.sysType.name;
final productDao = app.dataBase.getProductDao;
final productDao = appC.dataBase.getProductDao;
List<ProductEntity> list = await productDao.getDefault(
sysType,
hourType.value.code,
+66 -95
View File
@@ -1,8 +1,10 @@
import 'package:common_utils/common_utils.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:common_utils/common_utils.dart';
import 'package:get/get.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:forui/forui.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import 'index.dart';
@@ -11,71 +13,33 @@ class CanteenProductPage extends GetView<CanteenProductController> {
const CanteenProductPage({super.key});
// 头部
Widget _buildHeader(BuildContext context, double headerHeight) {
Widget _buildHeader(double headerHeight) {
final context = Get.context!;
final theme = FTheme.of(context);
return <Widget>[
FIcon(
FAssets.icons.chevronLeft,
size: theme.typography.xl4.fontSize,
).alignLeft().width(headerHeight).onTap(() => Get.back()),
Obx(() => controller.classifyList
.map(
(v) {
final currentIndex = controller.currentTabIndex.value;
final target = controller.classifyList[currentIndex];
final active = target.id == v.id;
return FButton(
style:
active ? FButtonStyle.primary : FButtonStyle.secondary,
label: Text(
v.name,
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: theme.typography.xl.copyWith(
color: active
? theme.colorScheme.secondary
: theme.colorScheme.primary,
),
).center().width(120.w),
onPress: () => controller.doTab(
controller.classifyList.indexWhere((i) => i.id == v.id),
),
);
},
)
.toList()
.toRowSpace(space: 20.w))
.scrollable(scrollDirection: Axis.horizontal)
.expanded(),
appRadioHourTypeDialog(
context,
controller.hourTypeC,
).width(300.w),
].toRow();
}
// 主体部分
Widget _buildMain(BuildContext context) {
final width = context.width;
final theme = FTheme.of(context);
return <Widget>[
_buildProduct(context).expanded(),
SizedBox(width: 15.w),
_buildUser(context).width(width * 0.25).decorated(
border: Border.all(
color: theme.colorScheme.primary,
width: 1,
),
borderRadius: theme.style.borderRadius,
),
)
.alignLeft()
.width(headerHeight)
.onTap(() => Get.offAndToNamed(RouteNames.panel)),
Obx(
() => orderRowClassify(
context,
classifyList: controller.classifyList,
currentTabIndex: controller.currentTabIndex,
onChange: (tabIndex) => controller.doTab(tabIndex),
),
).scrollable(scrollDirection: Axis.horizontal).expanded(),
appRadioHourTypeDialog(context, controller.hourTypeC).width(300.w),
].toRow();
}
// 商品
Widget _buildProduct(BuildContext context) {
Widget _buildProduct() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
builder: (BuildContext _, BoxConstraints constraints) {
const spacing = 10;
const runSpacing = 10;
double maxHeight = constraints.maxHeight;
@@ -166,31 +130,31 @@ class CanteenProductPage extends GetView<CanteenProductController> {
}
// 用户信息
Widget _buildUser(BuildContext context) {
final theme = FTheme.of(context);
Widget _buildUser() {
final theme = FTheme.of(Get.context!);
return <Widget>[
<Widget>[
Obx(() {
final payUser = controller.payUser.value;
return appUserInfo(
context,
Get.context!,
username: payUser?.username,
balance: payUser?.walletBalance,
avatar: payUser?.userAvatar,
);
}).width(400.w),
].toRow(mainAxisAlignment: MainAxisAlignment.center),
SizedBox(height: 10.h),
FDivider(
style: theme.dividerStyles.verticalStyle.copyWith(
color: theme.colorScheme.primary,
padding: EdgeInsets.zero,
}).width(400.w).center(),
SizedBox(height: 10.h),
FDivider(
style: theme.dividerStyles.verticalStyle.copyWith(
color: theme.colorScheme.primary,
padding: EdgeInsets.zero,
),
),
),
Text(
"已点菜品",
style: theme.typography.xl2,
).alignLeft(),
Text(
"已点菜品",
style: theme.typography.xl2,
).alignLeft(),
].toColumn(),
Obx(
() => ListView.builder(
padding: EdgeInsets.zero,
@@ -198,7 +162,7 @@ class CanteenProductPage extends GetView<CanteenProductController> {
itemBuilder: (context, index) {
final current = controller.shopCardList[index];
return orderSelectPanel(
context,
Get.context!,
label: current.productName,
price: current.productPrice,
total: current.productNumber,
@@ -209,14 +173,14 @@ class CanteenProductPage extends GetView<CanteenProductController> {
},
),
).expanded(),
Obx(
() => orderAllPrice(
context,
totalPrice: controller.totalPrice.value,
amountMealPrice: controller.amountMealPrice.value,
),
),
<Widget>[
Obx(
() => orderAllPrice(
Get.context!,
totalPrice: controller.totalPrice.value,
amountMealPrice: controller.amountMealPrice.value,
),
),
SizedBox(height: 20.h),
<Widget>[
FButton(
@@ -245,29 +209,36 @@ class CanteenProductPage extends GetView<CanteenProductController> {
}
// 主视图
Widget _buildView(BuildContext context) {
Widget _buildView() {
final context = Get.context!;
final width = context.width;
final theme = FTheme.of(context);
return <Widget>[
_buildMain(context).marginOnly(bottom: 20.h).expanded(),
].toColumn();
_buildProduct().expanded(),
SizedBox(width: 15.w),
_buildUser().width(width * 0.25).decorated(
border: Border.all(
color: theme.colorScheme.primary,
width: 1,
),
borderRadius: theme.style.borderRadius,
),
].toRow().marginOnly(bottom: 20.h);
}
@override
Widget build(BuildContext context) {
final height = context.height;
final headerHeight = height * 0.08;
final height = 90;
return GetBuilder<CanteenProductController>(
init: CanteenProductController(),
init: Get.find<CanteenProductController>(),
id: "canteen_product",
builder: (_) {
return FScaffold(
header: _buildHeader(
context,
headerHeight,
)
.height(headerHeight)
.padding(vertical: 30.h, horizontal: 10.w)
.decorated(),
content: _buildView(context),
header: _buildHeader(height.h)
.height(height.h)
.padding(vertical: 30.h, horizontal: 10.w),
content: _buildView(),
contentPad: true,
resizeToAvoidBottomInset: false,
);
},
+11 -6
View File
@@ -11,7 +11,7 @@ class PanelController extends GetxController {
RxList<PanelItem> panelBtnList = <PanelItem>[
PanelItem(title: "购买", visible: false, type: PanelType.supermarketOrder),
PanelItem(title: "点餐", visible: false, type: PanelType.canteenOrder),
PanelItem(title: "取餐", visible: true, type: PanelType.takeFood),
PanelItem(title: "取餐", visible: false, type: PanelType.takeFood),
PanelItem(title: "交易查询", visible: true, type: PanelType.orderHistory),
PanelItem(title: "开卡管理", visible: true, type: PanelType.cardActive),
PanelItem(title: "设置", visible: true, type: PanelType.setting),
@@ -21,15 +21,17 @@ class PanelController extends GetxController {
final canteenMenus = [
PanelType.canteenOrder,
PanelType.takeFood,
];
final supermarketMenus = [
PanelType.supermarketOrder,
];
_initData() async {
@override
void onInit() async {
super.onInit();
await _updateMenus();
update(["panel"]);
}
@override
@@ -38,15 +40,19 @@ class PanelController extends GetxController {
_initData();
}
_initData() async {
update(["panel"]);
}
Future<void> doBtn(PanelType type) async {
switch (type) {
case PanelType.supermarketOrder:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.supermarketProduct);
Get.offAllNamed(RouteNames.supermarketProduct);
break;
case PanelType.canteenOrder:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.canteenProduct);
Get.offAllNamed(RouteNames.canteenProduct);
break;
case PanelType.takeFood:
if (!await _checkIsBind()) return;
@@ -75,7 +81,6 @@ class PanelController extends GetxController {
Get.offAndToNamed(RouteNames.login);
break;
case PanelType.test:
await AppFaceTool.jumpFacePage();
break;
default:
break;
+3 -1
View File
@@ -87,6 +87,7 @@ class SettingController extends GetxController {
if (payType == null) continue;
usePayList.add(payType);
}
usePayList.sort((pren, next) => pren.code.compareTo(next.code));
sysSetting.value?.usePayDisplayType = usePayList;
await AppSettingTool.setSysSetting(sysSetting.value!);
});
@@ -131,7 +132,8 @@ class SettingController extends GetxController {
maskType: EasyLoadingMaskType.black,
);
try {
await SyncConfigTool.autoSyncSysInfo();
final setting = await SyncConfigTool.autoSyncSysInfo();
if (setting != null) sysSetting.value = setting;
Toast.success(msg: "同步设备信息成功");
EasyLoading.dismiss();
} catch (e, stack) {
@@ -16,9 +16,9 @@ Future<void> _bindServiceDialog(BuildContext context, SysSetting sys) async {
uniqueCodeC.text = sys.serviceId ?? "";
} else if (AppSysTool.isDev()) {
// 超市
uniqueCodeC.text = "1894303392833716226";
// uniqueCodeC.text = "1894303392833716226";
// 测试
// uniqueCodeC.text = "1896157295523049473";
uniqueCodeC.text = "1896157295523049473";
}
await showAdaptiveDialog(
context: context,
+11 -9
View File
@@ -1,6 +1,8 @@
import 'package:get/get.dart';
class SupermarketOrderController extends GetxController {
import 'package:pj_supermarket_cloud/common/index.dart';
class SupermarketOrderController extends GetxController with OrderMixin {
SupermarketOrderController();
_initData() {
@@ -9,10 +11,10 @@ class SupermarketOrderController extends GetxController {
void onTap() {}
// @override
// void onInit() {
// super.onInit();
// }
@override
void onInit() {
super.onInit();
}
@override
void onReady() {
@@ -20,8 +22,8 @@ class SupermarketOrderController extends GetxController {
_initData();
}
// @override
// void onClose() {
// super.onClose();
// }
@override
void onClose() {
super.onClose();
}
}
+30 -14
View File
@@ -3,11 +3,36 @@ import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import 'index.dart';
class SupermarketOrderPage extends GetView<SupermarketOrderController> {
const SupermarketOrderPage({super.key});
// 头部
Widget _buildHeader(double headerHeight) {
final context = Get.context!;
final theme = FTheme.of(context);
return <Widget>[
FIcon(
FAssets.icons.chevronLeft,
size: theme.typography.xl4.fontSize,
)
.alignLeft()
.width(headerHeight)
.onTap(() => Get.offAndToNamed(RouteNames.panel)),
Obx(
() => orderRowClassify(
context,
classifyList: controller.classifyList,
currentTabIndex: controller.currentTabIndex,
onChange: (tabIndex) => controller.doTab(tabIndex),
),
).scrollable(scrollDirection: Axis.horizontal).expanded(),
].toRow();
}
// 主视图
Widget _buildView(BuildContext context) {
return const Center(
@@ -17,26 +42,17 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
@override
Widget build(BuildContext context) {
final theme = FTheme.of(context);
final height = context.height;
final height = 90;
return GetBuilder<SupermarketOrderController>(
init: SupermarketOrderController(),
id: "supermarket_order",
builder: (_) {
return FScaffold(
header: FHeader.nested(
title: Text("取餐"),
prefixActions: [
FHeaderAction.back(onPress: Get.back),
],
style: theme.headerStyle.nestedStyle.copyWith(
titleTextStyle: theme.typography.lg,
actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith(
size: theme.typography.xl2.fontSize,
),
),
).height(height * 0.1),
header: _buildHeader(height.h)
.height(height.h)
.padding(vertical: 30.h, horizontal: 10.w),
content: _buildView(context),
contentPad: true,
resizeToAvoidBottomInset: false,
);
},
+4 -8
View File
@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
// import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart';
import 'package:forui/forui.dart';
// import 'package:forui/forui.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import 'package:pj_supermarket_cloud/sub_screen/page/index.dart';
@@ -37,7 +37,6 @@ class _SubAppPageState extends State<SubAppPage> {
@override
Widget build(BuildContext context) {
final theme = FTheme.of(context);
return MaterialApp(
navigatorKey: SubNavigatorKey.navigatorKey,
debugShowCheckedModeBanner: false,
@@ -45,11 +44,8 @@ class _SubAppPageState extends State<SubAppPage> {
SubRouteNames.subProduct: (context) => const SubProductPage(),
},
home: Scaffold(
backgroundColor: theme.colorScheme.background,
body: Text(
'欢迎使用',
style: theme.typography.xl4,
).center(),
backgroundColor: Colors.white,
body: Text('欢迎使用'),
),
);
}
+8 -8
View File
@@ -1,10 +1,8 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class SubProductPage extends StatefulWidget {
const SubProductPage({super.key});
@@ -19,10 +17,10 @@ class _SubProductPageState extends State<SubProductPage> {
void initState() {
super.initState();
_streamSubscription = SubScreenPlugin.viceStream.listen((event) {
dynamic params = event.arguments;
final action = SubScreenAction.values.fromCode(event.method);
if (action == null) return;
if (action == SubScreenAction.updateCard) {}
// dynamic params = event.arguments;
// final action = SubScreenAction.values.fromCode(event.method);
// if (action == null) return;
// if (action == SubScreenAction.updateCard) {}
});
}
@@ -34,6 +32,8 @@ class _SubProductPageState extends State<SubProductPage> {
@override
Widget build(BuildContext context) {
return Container();
return Container(
color: Colors.white,
);
}
}
+92 -4
View File
@@ -142,6 +142,30 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.9.4"
cached_network_image:
dependency: "direct main"
description:
name: cached_network_image
sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.4.1"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.1"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
characters:
dependency: transitive
description:
@@ -346,10 +370,10 @@ packages:
dependency: "direct main"
description:
name: external_path
sha256: e6d70bd47ee25d164287ecab65426684825439c6a39ee1895c6193d65576ee13
sha256: "68a18a2aa51ec012d7013ea2a80305dc5372f3577a2bbcc7dcc5550b25a5a73b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
version: "2.2.0"
fake_async:
dependency: transitive
description:
@@ -411,6 +435,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.4.1"
flutter_easyloading:
dependency: "direct main"
description:
@@ -802,6 +834,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.6"
octo_image:
dependency: transitive
description:
name: octo_image
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
package_config:
dependency: transitive
description:
@@ -1018,6 +1058,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.3"
rxdart:
dependency: transitive
description:
name: rxdart
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.28.0"
shelf:
dependency: transitive
description:
@@ -1071,14 +1119,30 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.0"
sqflite:
dependency: "direct main"
description:
name: sqflite
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
version: "2.4.1"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.0"
sqflite_common:
dependency: transitive
description:
@@ -1095,6 +1159,22 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.4+4"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.1+1"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.0"
sqlite3:
dependency: transitive
description:
@@ -1239,6 +1319,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.2"
uuid:
dependency: transitive
description:
name: uuid
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.5.1"
vector_graphics:
dependency: transitive
description:
+5 -5
View File
@@ -27,7 +27,7 @@ dependencies:
# 图片处理
image: ^4.3.0
# 图片缓存
# cached_network_image: 3.3.1
cached_network_image: ^3.4.1
# 表格
data_table_2: ^2.5.18
# 分页
@@ -40,18 +40,18 @@ dependencies:
# 权限判断
permission_handler: ^11.4.0
# 串口
flutter_libserialport: 0.5.0
flutter_libserialport: ^0.5.0
# 状态管理、路由
get: ^4.7.2
# 双屏
flutter_subscreen_plugin: 1.3.2+5
flutter_subscreen_plugin: ^1.3.2+5
# 数据库
sqflite: 2.3.2
sqflite: 2.4.1
floor: 1.4.2
# json序列化
json_annotation: ^4.9.0
# 外部路径获取
external_path: ^2.0.1
external_path: ^2.2.0
# 获取唯一id
android_id: ^0.4.0
# 监听网络状态