268 lines
7.1 KiB
Dart
268 lines
7.1 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:common_utils/common_utils.dart';
|
|
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
|
import 'package:forui/forui.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:pj_supermarket_cloud/common/index.dart';
|
|
|
|
class SteelyardController extends GetxController {
|
|
/// **************** start 回调函数 start ****************
|
|
|
|
// |开始称重|的回调
|
|
VoidCallback? onWeightStart;
|
|
|
|
// |确定重量|的回调
|
|
VoidCallback? onWeightSubmit;
|
|
|
|
// |取消|的回调
|
|
VoidCallback? onWeightCancel;
|
|
|
|
/// **************** end 回调函数 end ****************
|
|
|
|
static const _tag = "称重视图组件";
|
|
|
|
final appC = Get.find<AppControl>();
|
|
|
|
// 称重商品
|
|
SupermarketSpuEntity? _product;
|
|
|
|
// 重量
|
|
RxDouble widget = RxDouble(0);
|
|
|
|
// 回调的重量
|
|
RxDouble callbackWidget = RxDouble(0);
|
|
|
|
// 价格
|
|
RxInt price = RxInt(0);
|
|
|
|
// 添加计时器
|
|
Timer? _noUpdateTimer;
|
|
static const _timeoutDuration = Duration(seconds: 3);
|
|
|
|
// 点击|开始称重|
|
|
void weightStartCallback() {
|
|
EasyLoading.show(
|
|
status: '准备中...',
|
|
maskType: EasyLoadingMaskType.black,
|
|
);
|
|
widget.value = 0;
|
|
callbackWidget.value = 0;
|
|
price.value = 0;
|
|
_listenSteelyard();
|
|
onWeightStart?.call();
|
|
TtsManage.speak("开始称重");
|
|
EasyLoading.dismiss();
|
|
}
|
|
|
|
// 点击|确定重量|
|
|
void weightSubmitCallback() {
|
|
EasyLoading.show(
|
|
status: '确定中...',
|
|
maskType: EasyLoadingMaskType.black,
|
|
);
|
|
_closeSerial();
|
|
onWeightSubmit?.call();
|
|
EasyLoading.dismiss();
|
|
}
|
|
|
|
// 点击|取消|
|
|
void weightCancelCallback() {
|
|
EasyLoading.show(
|
|
status: '取消中...',
|
|
maskType: EasyLoadingMaskType.black,
|
|
);
|
|
_closeSerial();
|
|
onWeightCancel?.call();
|
|
EasyLoading.dismiss();
|
|
}
|
|
|
|
// 打开称重
|
|
bool open(SupermarketSpuEntity current) {
|
|
final isOpen = _openSerial();
|
|
if (_product != null) {
|
|
Toast.error(msg: "正在称重中,请勿重复点击");
|
|
return false;
|
|
}
|
|
if (!isOpen) {
|
|
_closeStatus();
|
|
return false;
|
|
}
|
|
_closeStatus();
|
|
_product = current;
|
|
weightStartCallback();
|
|
return true;
|
|
}
|
|
|
|
void close() {
|
|
_closeStatus();
|
|
_closeSerial();
|
|
}
|
|
|
|
// 清除状态
|
|
_closeStatus() {
|
|
_product = null;
|
|
widget.value = 0;
|
|
callbackWidget.value = 0;
|
|
price.value = 0;
|
|
_noUpdateTimer?.cancel();
|
|
_noUpdateTimer = null;
|
|
}
|
|
|
|
// 打开称串口
|
|
bool _openSerial() {
|
|
if (appC.srialSteelyardManage.isConnect) {
|
|
appC.srialSteelyardManage.close();
|
|
}
|
|
appC.srialSteelyardManage.connect();
|
|
if (appC.srialSteelyardManage.isConnect) {
|
|
logger.i("|$_tag|打开称串口成功");
|
|
return true;
|
|
}
|
|
logger.e("|$_tag|打开称串口失败");
|
|
return false;
|
|
}
|
|
|
|
// 关闭串口
|
|
void _closeSerial() {
|
|
appC.srialSteelyardManage.close();
|
|
if (appC.srialSteelyardManage.isConnect) {
|
|
logger.e("|$_tag|关闭串口失败");
|
|
return;
|
|
}
|
|
logger.i("|$_tag|关闭串口成功");
|
|
}
|
|
|
|
// 监听串口
|
|
void _listenSteelyard() {
|
|
try {
|
|
if (_product == null) return;
|
|
appC.srialSteelyardManage.readerClose();
|
|
appC.srialSteelyardManage.listen((event) {
|
|
final w = appC.srialSteelyardManage.parseWidget(event);
|
|
if (ObjectUtil.isEmpty(w)) return;
|
|
// 保留两位小数并向上取整
|
|
final roundedWeight = (w! * 100).round() / 100;
|
|
callbackWidget.value = roundedWeight;
|
|
});
|
|
interval(
|
|
callbackWidget,
|
|
(callback) {
|
|
if (_product == null) return;
|
|
widget.value = callbackWidget.value;
|
|
// 获取价格
|
|
final productPrice = _getProudctPrice(_product!);
|
|
final p = (callbackWidget.value * productPrice).truncate().ceil();
|
|
price.value = p;
|
|
logger.i(
|
|
"|$_tag|重量|${widget.value}|单价|$productPrice|总价|${price.value}|",
|
|
);
|
|
// 重置超时计时器
|
|
_noUpdateTimer?.cancel();
|
|
_noUpdateTimer = Timer(_timeoutDuration, () {
|
|
if (widget.value > 0) {
|
|
weightSubmitCallback();
|
|
}
|
|
});
|
|
},
|
|
time: const Duration(milliseconds: 100),
|
|
);
|
|
} catch (e) {
|
|
_closeStatus();
|
|
logger.e("|$_tag|打开并监听称串口失败error|$e|");
|
|
}
|
|
}
|
|
|
|
// 获取当前商品的价格,有促销价先用促销价
|
|
int _getProudctPrice(SupermarketSpuEntity product) {
|
|
if (product.promotionPrice != 0) {
|
|
return product.promotionPrice;
|
|
}
|
|
return product.retailPrice;
|
|
}
|
|
}
|
|
|
|
Widget steelyardEmpty(BuildContext context) {
|
|
final theme = FTheme.of(context);
|
|
return <Widget>[
|
|
<Widget>[
|
|
FIcon(
|
|
FAssets.icons.layers,
|
|
size: theme.typography.xl2.fontSize,
|
|
),
|
|
SizedBox(width: 10.w),
|
|
Text(
|
|
"请将商品放置到电子称中,点击开始称重",
|
|
style: theme.typography.xl,
|
|
),
|
|
].toRow(mainAxisAlignment: MainAxisAlignment.center),
|
|
SizedBox(height: 10.w),
|
|
Text(
|
|
"注意:请将电子称上的物品全部清空再点击开始称重",
|
|
style: theme.typography.base,
|
|
),
|
|
].toColumn(mainAxisAlignment: MainAxisAlignment.center);
|
|
}
|
|
|
|
Widget steelyardWidget(BuildContext context) {
|
|
final steelyardC = Get.find<SteelyardController>();
|
|
final theme = FTheme.of(context);
|
|
return <Widget>[
|
|
<Widget>[
|
|
Text("重量:", style: theme.typography.xl2),
|
|
Obx(
|
|
() => Text(
|
|
"${steelyardC.widget.value}/kg",
|
|
style: theme.typography.xl2,
|
|
),
|
|
),
|
|
].toRow().alignLeft().width(300.w),
|
|
<Widget>[
|
|
Text("价格:", style: theme.typography.xl2),
|
|
Obx(
|
|
() => appPrice(context, steelyardC.price.value),
|
|
),
|
|
].toRow().alignLeft().width(200.w),
|
|
].toColumn(mainAxisAlignment: MainAxisAlignment.center);
|
|
}
|
|
|
|
Widget steelyardContainer(BuildContext context) {
|
|
final theme = FTheme.of(context);
|
|
final steelyardC = Get.find<SteelyardController>();
|
|
final textStyle = theme.typography.xl.copyWith(
|
|
color: theme.colorScheme.secondary,
|
|
);
|
|
const textWidth = 220;
|
|
return <Widget>[
|
|
Visibility(
|
|
visible: steelyardC.widget.value >= 0.1,
|
|
replacement: steelyardEmpty(context),
|
|
child: steelyardWidget(context),
|
|
).expanded(),
|
|
SizedBox(height: 100.h),
|
|
<Widget>[
|
|
// FButton(
|
|
// label: Text("开始称重", style: textStyle),
|
|
// onPress: () => controller.weightStartCallback(),
|
|
// ).width(textWidth.w),
|
|
// FButton(
|
|
// label: Text("确定重量", style: textStyle),
|
|
// onPress: () => controller.weightSubmitCallback(),
|
|
// ).width(textWidth.w),
|
|
FButton(
|
|
style: FButtonStyle.destructive,
|
|
label: Text("取消", style: textStyle),
|
|
onPress: () => steelyardC.weightCancelCallback(),
|
|
).width(textWidth.w),
|
|
]
|
|
.toRowSpace(
|
|
space: 50.w,
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
)
|
|
.marginOnly(top: 20.h),
|
|
].toColumn(mainAxisAlignment: MainAxisAlignment.center);
|
|
}
|