feat:使用本地tts
This commit is contained in:
1 parent
2490d4f9a0
commit
d656ce14eb
22 files changed
+184
-185
No files matched your search
@@ -61,6 +61,7 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation files('libs/AIKit.aar')
|
||||
|
||||
// rxjava
|
||||
implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
|
||||
|
||||
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
@@ -7,33 +8,35 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE" />
|
||||
</intent>
|
||||
</queries>
|
||||
<application
|
||||
android:label="pj_supermarket_cloud"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="pj_supermarket_cloud"
|
||||
android:requestRawExternalStorageAccess="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:exported="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
@@ -51,8 +54,8 @@
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@@ -10,8 +10,7 @@ class MainActivity : FlutterActivity() {
|
||||
// 人脸识别插件
|
||||
val flutterFaceDiscernPlugin = FlutterFaceDiscernPlugin()
|
||||
flutterEngine.plugins.add(flutterFaceDiscernPlugin)
|
||||
// tts插件
|
||||
|
||||
|
||||
// 箭头全局键盘插件
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,12 @@ class MainApp extends StatelessWidget {
|
||||
iconStyle: fTheme.style.iconStyle.copyWith(
|
||||
size: fTheme.typography.xl2.fontSize,
|
||||
),
|
||||
pagePadding: EdgeInsets.symmetric(vertical: 5.h, horizontal: 1.w),
|
||||
),
|
||||
);
|
||||
return GetMaterialApp(
|
||||
title: '收银机',
|
||||
defaultTransition: Transition.noTransition,
|
||||
initialRoute: RouteNames.load,
|
||||
getPages: RoutePages.list,
|
||||
enableLog: true,
|
||||
|
||||
@@ -20,6 +20,7 @@ enum PanelType implements BaseEnum {
|
||||
cardActive("60", "开卡管理"),
|
||||
printer("70", "打印测试"),
|
||||
logout("80", "退出登录"),
|
||||
test("90", "测试"),
|
||||
;
|
||||
|
||||
@override
|
||||
|
||||
@@ -39,6 +39,7 @@ class AppControl extends GetxController {
|
||||
serialCardManage.close();
|
||||
srialSteelyardManage.close();
|
||||
AppNetworkTool.closeListenNetwork();
|
||||
TtsManage.dispose();
|
||||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
@@ -52,6 +53,7 @@ class AppControl extends GetxController {
|
||||
await getDatabasesPath(),
|
||||
);
|
||||
await AppFileTool.backupSqlFile();
|
||||
await TtsManage.initialize();
|
||||
Get.offAllNamed(RouteNames.login);
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,9 @@ export './manage/print_manage.dart';
|
||||
export './manage/serial_card_manage.dart';
|
||||
export './manage/serial_steelyard_manage.dart';
|
||||
export './manage/scan_code_manage.dart';
|
||||
export './manage/tts_manage.dart';
|
||||
|
||||
export './plugs/face_discern_plugs.dart';
|
||||
export './plugs/local_tts_plugs.dart';
|
||||
|
||||
export './router/router_observer_tool.dart';
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:flutter_tts/flutter_tts.dart';
|
||||
|
||||
// 语音转文字
|
||||
class TtsManage {
|
||||
static final FlutterTts _flutterTts = FlutterTts();
|
||||
static bool _isInitialized = false;
|
||||
|
||||
// 初始化TTS
|
||||
static Future<void> initialize() async {
|
||||
if (!_isInitialized) {
|
||||
// 设置语言为中文
|
||||
await _flutterTts.setLanguage("zh-CN");
|
||||
// 设置音量
|
||||
await _flutterTts.setVolume(1.0);
|
||||
// 设置语速
|
||||
await _flutterTts.setSpeechRate(0.7);
|
||||
// 设置音调
|
||||
await _flutterTts.setPitch(1.0);
|
||||
// 设置使用本地引擎
|
||||
await _flutterTts.setIosAudioCategory(
|
||||
IosTextToSpeechAudioCategory.ambient,
|
||||
[
|
||||
IosTextToSpeechAudioCategoryOptions.allowBluetooth,
|
||||
IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP
|
||||
],
|
||||
);
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 播放文本
|
||||
static Future<void> speak(String text) async {
|
||||
await initialize();
|
||||
await _flutterTts.awaitSpeakCompletion(true);
|
||||
await _flutterTts.speak(text, focus: true);
|
||||
}
|
||||
|
||||
// 停止播放
|
||||
static Future<void> stop() async {
|
||||
await _flutterTts.stop();
|
||||
}
|
||||
|
||||
// 释放资源
|
||||
static Future<void> dispose() async {
|
||||
await _flutterTts.stop();
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class LocalTtsPlugs {
|
||||
static const String _tag = "本地tts插件";
|
||||
|
||||
static const MethodChannel _channel = MethodChannel(
|
||||
Constants.localTTSPlugsMethodChannel,
|
||||
);
|
||||
|
||||
static Future<bool> speeching({
|
||||
required String appId,
|
||||
required String str,
|
||||
String speed = "80",
|
||||
}) async {
|
||||
try {
|
||||
final pa = {
|
||||
"appId": appId,
|
||||
"str": str,
|
||||
"speed": speed,
|
||||
};
|
||||
await _channel.invokeMethod('speeching', pa);
|
||||
return true;
|
||||
} catch (e) {
|
||||
logger.w("|$_tag| jumpFaceDiscernPage 错误: $e");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,6 @@ class Constants {
|
||||
/// 静态资源 url
|
||||
static const ossUrl = apiUrl;
|
||||
|
||||
/// ttl android 插件方法管道
|
||||
static const localTTSPlugsMethodChannel = 'local/tts';
|
||||
|
||||
/// 人脸识别 插件方法管道
|
||||
static const facePlugsMethodChannel = 'local/face_discern';
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
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';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
Widget appNetworkImg(
|
||||
@@ -14,34 +16,11 @@ Widget appNetworkImg(
|
||||
double imgHeight = 60,
|
||||
BoxFit fit = BoxFit.cover,
|
||||
}) {
|
||||
return Image.network(
|
||||
AppNetworkTool.ossImage(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,
|
||||
|
||||
@@ -25,9 +25,6 @@ mixin OrderMixin {
|
||||
// 设备类型
|
||||
SysType _sysType = SysType.canteen;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
/// **************** end 需要重制 end ****************
|
||||
|
||||
// 分类
|
||||
@@ -316,18 +313,6 @@ mixin OrderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取商品渠道id
|
||||
String getOrderSourceTypeId() {
|
||||
String orderSourceTypeId = "";
|
||||
@@ -408,11 +393,6 @@ mixin OrderMixin {
|
||||
|
||||
/// **************** start 重制相关 start ****************
|
||||
|
||||
// 重置状态
|
||||
void closeStatus() {
|
||||
_speechingLock = false;
|
||||
}
|
||||
|
||||
/// **************** end 重制相关 end ****************
|
||||
|
||||
/// **************** start 副屏幕相关 start ****************
|
||||
|
||||
@@ -12,20 +12,21 @@ Widget orderProductCard(
|
||||
num price = 0.0,
|
||||
}) {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
appImg(image, width: double.infinity, height: 140.h),
|
||||
Text(name, style: theme.typography.lg),
|
||||
appPrice(context, price)
|
||||
]
|
||||
.toColumn(crossAxisAlignment: CrossAxisAlignment.center)
|
||||
.width(double.infinity)
|
||||
.decorated(
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: theme.style.borderRadius / 3,
|
||||
);
|
||||
return FCard(
|
||||
style: theme.cardStyle.copyWith(
|
||||
contentStyle: theme.cardStyle.contentStyle.copyWith(
|
||||
padding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
image: appImg(image, width: double.infinity, height: 150.h),
|
||||
subtitle: <Widget>[
|
||||
Text(name, style: theme.typography.lg),
|
||||
SizedBox(height: 5.h),
|
||||
appPrice(context, price),
|
||||
]
|
||||
.toColumn(crossAxisAlignment: CrossAxisAlignment.center)
|
||||
.width(double.infinity),
|
||||
).width(double.infinity);
|
||||
}
|
||||
|
||||
/// 菜品总价
|
||||
|
||||
@@ -58,9 +58,6 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
// 二维码识别结果
|
||||
ServiceQRCode? globalQrCode;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
// 人脸识别回调锁
|
||||
bool _faceCallbackLock = false;
|
||||
|
||||
@@ -96,7 +93,6 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
payUser.value = null;
|
||||
isRecognition.value = false;
|
||||
globalQrCode = null;
|
||||
_speechingLock = false;
|
||||
_faceCallbackLock = false;
|
||||
}
|
||||
|
||||
@@ -249,7 +245,7 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
isRecognition.value = false;
|
||||
await app.scanCodeManage.close();
|
||||
Toast.success(msg: "识别二维码成功");
|
||||
speeching("识别二维码成功");
|
||||
TtsManage.speak("识别二维码成功");
|
||||
});
|
||||
isRecognition.value = true;
|
||||
onDiscernUser?.call(payUser.value);
|
||||
@@ -275,7 +271,7 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
switch (status) {
|
||||
case SerialCardResStatus.success:
|
||||
if (ObjectUtil.isEmpty(card)) return;
|
||||
speeching("识别饭卡成功");
|
||||
TtsManage.speak("识别饭卡成功");
|
||||
final isNetwork = AppNetworkTool.isAutoNetwork();
|
||||
if (isNetwork) {
|
||||
final pa = {"card": card};
|
||||
@@ -442,19 +438,6 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
];
|
||||
return success.contains(type);
|
||||
}
|
||||
|
||||
/// 语音
|
||||
Future<void> speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> selectPayTypeDialog(BuildContext context) async {
|
||||
|
||||
@@ -48,8 +48,6 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
hourType.value = appSetting.hourType ?? ProductHourType.morning;
|
||||
hourTypeC.value = {hourType.value.code};
|
||||
sysType = SysType.canteen;
|
||||
// 重置状态
|
||||
closeStatus();
|
||||
_listenPayTypeSelectCallback();
|
||||
|
||||
/// **************** end 组件初始化 end ****************
|
||||
@@ -103,8 +101,6 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
app.scanCodeManage.close();
|
||||
// 路由监听
|
||||
routerBus?.cancel();
|
||||
// 重置状态
|
||||
closeStatus();
|
||||
mqUpdateListen?.cancel();
|
||||
hourTypeC.dispose();
|
||||
}
|
||||
@@ -233,12 +229,12 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
bool _validatePayUser() {
|
||||
bool flag = true;
|
||||
if (ObjectUtil.isEmpty(payUser.value?.walletBalance)) {
|
||||
speeching("用户钱包不存在");
|
||||
TtsManage.speak("用户钱包不存在");
|
||||
Toast.error(msg: "校验购物车失败,用户钱包不存在");
|
||||
return false;
|
||||
}
|
||||
if (payUser.value!.walletBalance! < totalPrice.value) {
|
||||
speeching("用户余额不足");
|
||||
TtsManage.speak("用户余额不足");
|
||||
Toast.error(msg: "校验购物车失败,用户余额不足");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
double maxHeight = constraints.maxHeight;
|
||||
double maxWidth = constraints.maxWidth;
|
||||
double itemWidth = (maxWidth - spacing * 5) / 6;
|
||||
double itemHeight = (maxHeight - (runSpacing + 40) * 3) / 3;
|
||||
double itemHeight = (maxHeight - (runSpacing + 30) * 3) / 3;
|
||||
return Obx(
|
||||
() => ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
|
||||
@@ -10,9 +10,6 @@ class CardActiveController extends GetxController {
|
||||
|
||||
SerialCardManage get serialCardManage => appC.serialCardManage;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
// table
|
||||
RxInt currentPage = 1.obs;
|
||||
|
||||
@@ -37,7 +34,6 @@ class CardActiveController extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_closeStatus();
|
||||
getTableList();
|
||||
}
|
||||
|
||||
@@ -50,7 +46,6 @@ class CardActiveController extends GetxController {
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
_closeStatus();
|
||||
}
|
||||
|
||||
Future<void> doPage({int? page}) async {
|
||||
@@ -119,12 +114,12 @@ class CardActiveController extends GetxController {
|
||||
case SerialCardResStatus.warning:
|
||||
break;
|
||||
case SerialCardResStatus.error:
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
TtsManage.speak("请在合适区域放置饭卡");
|
||||
Toast.error(msg: "请在合适区域放置饭卡");
|
||||
break;
|
||||
}
|
||||
};
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
TtsManage.speak("请在合适区域放置饭卡");
|
||||
serialCardManage.sendWrite(v.cardNumber!);
|
||||
} catch (e, stack) {
|
||||
logger.d("写卡失败error:|$e|stack:|$stack|");
|
||||
@@ -163,11 +158,11 @@ class CardActiveController extends GetxController {
|
||||
break;
|
||||
case SerialCardResStatus.error:
|
||||
Toast.error(msg: "请在合适区域放置饭卡");
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
TtsManage.speak("请在合适区域放置饭卡");
|
||||
break;
|
||||
}
|
||||
};
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
TtsManage.speak("请在合适区域放置饭卡");
|
||||
serialCardManage.sendRead();
|
||||
} catch (e, stack) {
|
||||
_closeReadStatus();
|
||||
@@ -183,7 +178,7 @@ class CardActiveController extends GetxController {
|
||||
final data = await WalletApi.openCardSuccess(pa);
|
||||
if (data == false) throw Error();
|
||||
EasyLoading.dismiss();
|
||||
_speeching("激活成功");
|
||||
TtsManage.speak("激活成功");
|
||||
Toast.success(msg: "激活成功");
|
||||
} catch (e, stack) {
|
||||
logger.e("激活饭卡请求失败error:|$e|stack:|$stack|");
|
||||
@@ -210,25 +205,8 @@ class CardActiveController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _closeReadStatus() {
|
||||
readLoading.value = false;
|
||||
readCardNumber.value = "未读取";
|
||||
}
|
||||
|
||||
// 重置状态
|
||||
void _closeStatus() {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ class PanelController extends GetxController {
|
||||
PanelItem(title: "开卡管理", visible: true, type: PanelType.cardActive),
|
||||
PanelItem(title: "设置", visible: true, type: PanelType.setting),
|
||||
PanelItem(title: "退出登录", visible: true, type: PanelType.logout),
|
||||
PanelItem(title: "测试", visible: true, type: PanelType.test),
|
||||
].obs;
|
||||
|
||||
final canteenMenus = [
|
||||
@@ -73,6 +74,10 @@ class PanelController extends GetxController {
|
||||
}
|
||||
Get.offAndToNamed(RouteNames.login);
|
||||
break;
|
||||
case PanelType.test:
|
||||
await TtsManage.initialize();
|
||||
await TtsManage.speak("购买成功1");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@ class TakeFoodController extends GetxController {
|
||||
|
||||
ServiceQRCode? globalQrCode;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
_initData() {
|
||||
update(["take_food"]);
|
||||
}
|
||||
@@ -42,7 +39,6 @@ class TakeFoodController extends GetxController {
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
_closeStatus();
|
||||
_initData();
|
||||
}
|
||||
|
||||
@@ -51,12 +47,6 @@ class TakeFoodController extends GetxController {
|
||||
super.onClose();
|
||||
// 二维码读头
|
||||
appC.serialCardManage.close();
|
||||
_closeStatus();
|
||||
}
|
||||
|
||||
// 重置状态
|
||||
void _closeStatus() {
|
||||
_speechingLock = false;
|
||||
}
|
||||
|
||||
doCancelPay() {
|
||||
@@ -170,7 +160,7 @@ class TakeFoodController extends GetxController {
|
||||
if (flag == false) throw Error();
|
||||
EasyLoading.dismiss();
|
||||
Toast.error(msg: "核销成功");
|
||||
_speeching("核销成功");
|
||||
TtsManage.speak("核销成功");
|
||||
doCancelPay();
|
||||
} catch (e, stack) {
|
||||
logger.e("获取订单详情错误error:|$e|stack:|$stack|");
|
||||
@@ -182,16 +172,4 @@ class TakeFoodController extends GetxController {
|
||||
void senSubScreen() {
|
||||
if (ObjectUtil.isEmpty(carList)) return;
|
||||
}
|
||||
|
||||
Future<void> _speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
cached_network_image_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_platform_interface
|
||||
sha256: ff0c949e323d2a1b52be73acce5b4a7b04063e61414c8ca542dbba47281630a7
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
cached_network_image_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
sha256: "6322dde7a5ad92202e64df659241104a43db20ed594c41ca18de1014598d7996"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
characters:
|
||||
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: a77f77806a790eb9ba0118a5a3a936e81c4fea2b61533033b2b0c3d50bbde5ea
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
flutter_easyloading:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -469,6 +501,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_tts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_tts
|
||||
sha256: baa3cb6b4990318460fe28bfa8c7869399e97223971532c02bd97c5e876aa3c5
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.2.2"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -794,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:
|
||||
@@ -1010,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:
|
||||
@@ -1063,6 +1119,14 @@ 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:
|
||||
@@ -1231,6 +1295,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:
|
||||
|
||||
@@ -26,12 +26,16 @@ dependencies:
|
||||
flutter_easyloading: ^3.0.5
|
||||
# 图片处理
|
||||
image: ^4.3.0
|
||||
# 图片缓存
|
||||
cached_network_image: 3.3.1
|
||||
# 表格
|
||||
data_table_2: ^2.5.18
|
||||
# 分页
|
||||
number_pagination: ^1.1.6
|
||||
# 日期选择
|
||||
syncfusion_flutter_datepicker: ^28.2.11
|
||||
# tts转语音
|
||||
flutter_tts: ^4.2.2
|
||||
|
||||
# 权限判断
|
||||
permission_handler: ^11.4.0
|
||||
|
||||
Reference in new issue
Block a user