feat:切换flutter版本
This commit is contained in:
1 parent
ee761ccc48
commit
72443f7abf
32 files changed
+536
-375
No files matched your search
@@ -43,3 +43,6 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
# FVM Version Cache
|
||||
.fvm/
|
||||
Vendored
+26
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"dart.flutterSdkPath": ".fvm/versions/3.27.4"
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
|
||||
+1
-8
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+75
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
},
|
||||
|
||||
@@ -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('欢迎使用'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
# 监听网络状态
|
||||
|
||||
Reference in new issue
Block a user