Files
biz_xfj_cloud/lib/common/widgets/order/steelyard_container.dart
T

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);
}