diff --git a/android/app/build.gradle b/android/app/build.gradle
index 31d0601..09658ad 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -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'
diff --git a/android/app/libs/AIKit.aar b/android/app/libs/AIKit.aar
new file mode 100644
index 0000000..ca6f61f
Binary files /dev/null and b/android/app/libs/AIKit.aar differ
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a1eaa9c..86ad7e3 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
+
@@ -7,33 +8,35 @@
+
+
+ android:icon="@mipmap/ic_launcher"
+ android:label="pj_supermarket_cloud"
+ android:requestRawExternalStorageAccess="true">
+ android:name="io.flutter.embedding.android.NormalTheme"
+ android:resource="@style/NormalTheme" />
-
-
+
+
@@ -51,8 +54,8 @@
-
-
+
+
diff --git a/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt
index 3555471..ac7a6a9 100644
--- a/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt
+++ b/android/app/src/main/kotlin/com/example/pj_supermarket_cloud/MainActivity.kt
@@ -10,8 +10,7 @@ class MainActivity : FlutterActivity() {
// 人脸识别插件
val flutterFaceDiscernPlugin = FlutterFaceDiscernPlugin()
flutterEngine.plugins.add(flutterFaceDiscernPlugin)
- // tts插件
-
+
// 箭头全局键盘插件
}
}
diff --git a/lib/app.dart b/lib/app.dart
index b70a1bd..1dc4d7d 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -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,
diff --git a/lib/common/models/page/panel_page_models.dart b/lib/common/models/page/panel_page_models.dart
index 9a4f993..2493435 100644
--- a/lib/common/models/page/panel_page_models.dart
+++ b/lib/common/models/page/panel_page_models.dart
@@ -20,6 +20,7 @@ enum PanelType implements BaseEnum {
cardActive("60", "开卡管理"),
printer("70", "打印测试"),
logout("80", "退出登录"),
+ test("90", "测试"),
;
@override
diff --git a/lib/common/utils/app/control/app_control.dart b/lib/common/utils/app/control/app_control.dart
index 05faaae..965cff5 100644
--- a/lib/common/utils/app/control/app_control.dart
+++ b/lib/common/utils/app/control/app_control.dart
@@ -39,6 +39,7 @@ class AppControl extends GetxController {
serialCardManage.close();
srialSteelyardManage.close();
AppNetworkTool.closeListenNetwork();
+ TtsManage.dispose();
}
Future initAsync() async {
@@ -52,6 +53,7 @@ class AppControl extends GetxController {
await getDatabasesPath(),
);
await AppFileTool.backupSqlFile();
+ await TtsManage.initialize();
Get.offAllNamed(RouteNames.login);
}
}
diff --git a/lib/common/utils/index.dart b/lib/common/utils/index.dart
index fcbcd12..6c5b872 100644
--- a/lib/common/utils/index.dart
+++ b/lib/common/utils/index.dart
@@ -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';
diff --git a/lib/common/utils/manage/tts_manage.dart b/lib/common/utils/manage/tts_manage.dart
new file mode 100644
index 0000000..b13140e
--- /dev/null
+++ b/lib/common/utils/manage/tts_manage.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 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 speak(String text) async {
+ await initialize();
+ await _flutterTts.awaitSpeakCompletion(true);
+ await _flutterTts.speak(text, focus: true);
+ }
+
+ // 停止播放
+ static Future stop() async {
+ await _flutterTts.stop();
+ }
+
+ // 释放资源
+ static Future dispose() async {
+ await _flutterTts.stop();
+ }
+}
diff --git a/lib/common/utils/plugs/local_tts_plugs.dart b/lib/common/utils/plugs/local_tts_plugs.dart
deleted file mode 100644
index 0df4765..0000000
--- a/lib/common/utils/plugs/local_tts_plugs.dart
+++ /dev/null
@@ -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 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;
- }
-}
diff --git a/lib/common/values/constants.dart b/lib/common/values/constants.dart
index 398dddd..47fd9da 100644
--- a/lib/common/values/constants.dart
+++ b/lib/common/values/constants.dart
@@ -17,9 +17,6 @@ class Constants {
/// 静态资源 url
static const ossUrl = apiUrl;
- /// ttl android 插件方法管道
- static const localTTSPlugsMethodChannel = 'local/tts';
-
/// 人脸识别 插件方法管道
static const facePlugsMethodChannel = 'local/face_discern';
diff --git a/lib/common/widgets/app/app_img.dart b/lib/common/widgets/app/app_img.dart
index 7f04444..f30b80d 100644
--- a/lib/common/widgets/app/app_img.dart
+++ b/lib/common/widgets/app/app_img.dart
@@ -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,
diff --git a/lib/common/widgets/order/mixin/order_mixin.dart b/lib/common/widgets/order/mixin/order_mixin.dart
index ebaf2b2..ab9aab8 100644
--- a/lib/common/widgets/order/mixin/order_mixin.dart
+++ b/lib/common/widgets/order/mixin/order_mixin.dart
@@ -25,9 +25,6 @@ mixin OrderMixin {
// 设备类型
SysType _sysType = SysType.canteen;
- // 语音锁
- bool _speechingLock = false;
-
/// **************** end 需要重制 end ****************
// 分类
@@ -316,18 +313,6 @@ mixin OrderMixin {
}
}
- Future 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 ****************
diff --git a/lib/common/widgets/order/order_common.dart b/lib/common/widgets/order/order_common.dart
index bfc5342..e82b755 100644
--- a/lib/common/widgets/order/order_common.dart
+++ b/lib/common/widgets/order/order_common.dart
@@ -12,20 +12,21 @@ Widget orderProductCard(
num price = 0.0,
}) {
final theme = FTheme.of(context);
- return [
- 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: [
+ Text(name, style: theme.typography.lg),
+ SizedBox(height: 5.h),
+ appPrice(context, price),
+ ]
+ .toColumn(crossAxisAlignment: CrossAxisAlignment.center)
+ .width(double.infinity),
+ ).width(double.infinity);
}
/// 菜品总价
diff --git a/lib/common/widgets/order/select_pay_type_dialog.dart b/lib/common/widgets/order/select_pay_type_dialog.dart
index 844120b..b2817d1 100644
--- a/lib/common/widgets/order/select_pay_type_dialog.dart
+++ b/lib/common/widgets/order/select_pay_type_dialog.dart
@@ -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 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 selectPayTypeDialog(BuildContext context) async {
diff --git a/lib/pages/canteen_product/controller.dart b/lib/pages/canteen_product/controller.dart
index 7e39c0e..febe47b 100644
--- a/lib/pages/canteen_product/controller.dart
+++ b/lib/pages/canteen_product/controller.dart
@@ -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;
}
diff --git a/lib/pages/canteen_product/view.dart b/lib/pages/canteen_product/view.dart
index b9183fd..28e3a55 100644
--- a/lib/pages/canteen_product/view.dart
+++ b/lib/pages/canteen_product/view.dart
@@ -81,7 +81,7 @@ class CanteenProductPage extends GetView {
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,
diff --git a/lib/pages/card_active/controller.dart b/lib/pages/card_active/controller.dart
index 377a526..012ec08 100644
--- a/lib/pages/card_active/controller.dart
+++ b/lib/pages/card_active/controller.dart
@@ -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 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 _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;
- }
}
diff --git a/lib/pages/panel/controller.dart b/lib/pages/panel/controller.dart
index 70227aa..6641bdc 100644
--- a/lib/pages/panel/controller.dart
+++ b/lib/pages/panel/controller.dart
@@ -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;
}
diff --git a/lib/pages/take_food/controller.dart b/lib/pages/take_food/controller.dart
index 3896cc4..a239d4e 100644
--- a/lib/pages/take_food/controller.dart
+++ b/lib/pages/take_food/controller.dart
@@ -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 _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;
- }
- }
}
diff --git a/pubspec.lock b/pubspec.lock
index 9ffbb3f..7b423dc 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -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:
diff --git a/pubspec.yaml b/pubspec.yaml
index 92ba5c9..a7a55b1 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -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