feat:超市商品页面
This commit is contained in:
1 parent
e7c2fcd733
commit
de2f5e14b6
14 files changed
+218
-85
No files matched your search
@@ -126,7 +126,7 @@ enum WalletType implements BaseEnum {
|
||||
}
|
||||
|
||||
/// 商品性质
|
||||
enum SupermarketNature implements BaseEnum {
|
||||
enum ProductNature implements BaseEnum {
|
||||
DEFAULT("1", "普通商品"),
|
||||
WEIGHT("2", "电子称称重商品"),
|
||||
;
|
||||
@@ -136,5 +136,5 @@ enum SupermarketNature implements BaseEnum {
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const SupermarketNature(this.code, this.title);
|
||||
const ProductNature(this.code, this.title);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ class _$AppDatabase extends AppDatabase {
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `supermarket_code` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `serviceUniqueCode` TEXT NOT NULL, `spuId` TEXT NOT NULL, `unitId` TEXT NOT NULL, `barCode` TEXT NOT NULL)');
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `shop_card` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `orderId` INTEGER NOT NULL, `productServiceUniqueCode` TEXT NOT NULL, `productName` TEXT NOT NULL, `productPic` TEXT NOT NULL, `productPrice` INTEGER NOT NULL, `productNumber` INTEGER NOT NULL, `productWidget` REAL NOT NULL, `totalPrice` INTEGER NOT NULL)');
|
||||
'CREATE TABLE IF NOT EXISTS `shop_card` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `orderId` INTEGER NOT NULL, `productServiceUniqueCode` TEXT NOT NULL, `productName` TEXT NOT NULL, `productPic` TEXT NOT NULL, `productPrice` INTEGER NOT NULL, `nature` TEXT NOT NULL, `productNumber` INTEGER NOT NULL, `productWidget` REAL NOT NULL, `totalPrice` INTEGER NOT NULL)');
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `classify` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `serviceUniqueCode` TEXT NOT NULL, `sysType` TEXT NOT NULL, `name` TEXT NOT NULL, `categoryType` TEXT NOT NULL, `sort` INTEGER NOT NULL, `createTime` TEXT NOT NULL, `updateTime` TEXT NOT NULL, `delFlag` INTEGER NOT NULL)');
|
||||
await database.execute(
|
||||
@@ -853,6 +853,7 @@ class _$ShopCardDao extends ShopCardDao {
|
||||
'productName': item.productName,
|
||||
'productPic': item.productPic,
|
||||
'productPrice': item.productPrice,
|
||||
'nature': _supermarketNatureConverter.encode(item.nature),
|
||||
'productNumber': item.productNumber,
|
||||
'productWidget': item.productWidget,
|
||||
'totalPrice': item.totalPrice
|
||||
@@ -868,6 +869,7 @@ class _$ShopCardDao extends ShopCardDao {
|
||||
'productName': item.productName,
|
||||
'productPic': item.productPic,
|
||||
'productPrice': item.productPrice,
|
||||
'nature': _supermarketNatureConverter.encode(item.nature),
|
||||
'productNumber': item.productNumber,
|
||||
'productWidget': item.productWidget,
|
||||
'totalPrice': item.totalPrice
|
||||
@@ -883,6 +885,7 @@ class _$ShopCardDao extends ShopCardDao {
|
||||
'productName': item.productName,
|
||||
'productPic': item.productPic,
|
||||
'productPrice': item.productPrice,
|
||||
'nature': _supermarketNatureConverter.encode(item.nature),
|
||||
'productNumber': item.productNumber,
|
||||
'productWidget': item.productWidget,
|
||||
'totalPrice': item.totalPrice
|
||||
@@ -911,6 +914,7 @@ class _$ShopCardDao extends ShopCardDao {
|
||||
productName: row['productName'] as String,
|
||||
productPic: row['productPic'] as String,
|
||||
productPrice: row['productPrice'] as int,
|
||||
nature: _supermarketNatureConverter.decode(row['nature'] as String),
|
||||
productNumber: row['productNumber'] as int,
|
||||
productWidget: row['productWidget'] as double,
|
||||
totalPrice: row['totalPrice'] as int),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:floor/floor.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
part 'shop_card_entity.g.dart';
|
||||
|
||||
@@ -25,6 +26,9 @@ class ShopCardEntity {
|
||||
/// 商品价格(分)
|
||||
int productPrice;
|
||||
|
||||
/// 商品性质
|
||||
ProductNature nature;
|
||||
|
||||
/// 数量 食堂特有
|
||||
int productNumber;
|
||||
|
||||
@@ -41,6 +45,7 @@ class ShopCardEntity {
|
||||
required this.productName,
|
||||
required this.productPic,
|
||||
required this.productPrice,
|
||||
required this.nature,
|
||||
required this.productNumber,
|
||||
required this.productWidget,
|
||||
required this.totalPrice,
|
||||
|
||||
@@ -14,6 +14,7 @@ ShopCardEntity _$ShopCardEntityFromJson(Map<String, dynamic> json) =>
|
||||
productName: json['productName'] as String,
|
||||
productPic: json['productPic'] as String,
|
||||
productPrice: (json['productPrice'] as num).toInt(),
|
||||
nature: $enumDecode(_$ProductNatureEnumMap, json['nature']),
|
||||
productNumber: (json['productNumber'] as num).toInt(),
|
||||
productWidget: (json['productWidget'] as num).toDouble(),
|
||||
totalPrice: (json['totalPrice'] as num).toInt(),
|
||||
@@ -27,7 +28,13 @@ Map<String, dynamic> _$ShopCardEntityToJson(ShopCardEntity instance) =>
|
||||
'productName': instance.productName,
|
||||
'productPic': instance.productPic,
|
||||
'productPrice': instance.productPrice,
|
||||
'nature': _$ProductNatureEnumMap[instance.nature]!,
|
||||
'productNumber': instance.productNumber,
|
||||
'productWidget': instance.productWidget,
|
||||
'totalPrice': instance.totalPrice,
|
||||
};
|
||||
|
||||
const _$ProductNatureEnumMap = {
|
||||
ProductNature.DEFAULT: 'DEFAULT',
|
||||
ProductNature.WEIGHT: 'WEIGHT',
|
||||
};
|
||||
@@ -24,7 +24,7 @@ class SupermarketSpuEntity {
|
||||
String productName;
|
||||
|
||||
/// 商品性质(字典)
|
||||
SupermarketNature productNature;
|
||||
ProductNature productNature;
|
||||
|
||||
/// 条码
|
||||
String? barCode;
|
||||
|
||||
@@ -14,8 +14,7 @@ SupermarketSpuEntity _$SupermarketSpuEntityFromJson(
|
||||
classifyServiceUniqueCode: json['classifyServiceUniqueCode'] as String,
|
||||
productCode: json['productCode'] as String,
|
||||
productName: json['productName'] as String,
|
||||
productNature:
|
||||
$enumDecode(_$SupermarketNatureEnumMap, json['productNature']),
|
||||
productNature: $enumDecode(_$ProductNatureEnumMap, json['productNature']),
|
||||
barCode: json['barCode'] as String?,
|
||||
packageNum: (json['packageNum'] as num).toInt(),
|
||||
unit: json['unit'] as String,
|
||||
@@ -40,7 +39,7 @@ Map<String, dynamic> _$SupermarketSpuEntityToJson(
|
||||
'classifyServiceUniqueCode': instance.classifyServiceUniqueCode,
|
||||
'productCode': instance.productCode,
|
||||
'productName': instance.productName,
|
||||
'productNature': _$SupermarketNatureEnumMap[instance.productNature]!,
|
||||
'productNature': _$ProductNatureEnumMap[instance.productNature]!,
|
||||
'barCode': instance.barCode,
|
||||
'packageNum': instance.packageNum,
|
||||
'unit': instance.unit,
|
||||
@@ -57,7 +56,7 @@ Map<String, dynamic> _$SupermarketSpuEntityToJson(
|
||||
'delFlag': instance.delFlag,
|
||||
};
|
||||
|
||||
const _$SupermarketNatureEnumMap = {
|
||||
SupermarketNature.DEFAULT: 'DEFAULT',
|
||||
SupermarketNature.WEIGHT: 'WEIGHT',
|
||||
const _$ProductNatureEnumMap = {
|
||||
ProductNature.DEFAULT: 'DEFAULT',
|
||||
ProductNature.WEIGHT: 'WEIGHT',
|
||||
};
|
||||
@@ -107,15 +107,14 @@ class ProductHourTypeConverter extends TypeConverter<ProductHourType, String> {
|
||||
}
|
||||
}
|
||||
|
||||
class SupermarketNatureConverter
|
||||
extends TypeConverter<SupermarketNature, String> {
|
||||
class SupermarketNatureConverter extends TypeConverter<ProductNature, String> {
|
||||
@override
|
||||
SupermarketNature decode(String databaseValue) {
|
||||
return SupermarketNature.values.byName(databaseValue);
|
||||
ProductNature decode(String databaseValue) {
|
||||
return ProductNature.values.byName(databaseValue);
|
||||
}
|
||||
|
||||
@override
|
||||
String encode(SupermarketNature value) {
|
||||
String encode(ProductNature value) {
|
||||
return value.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,8 +351,8 @@ abstract class SyncProductTool {
|
||||
classifyServiceUniqueCode: v.categoryId ?? "-1",
|
||||
productCode: v.productCode ?? "-1",
|
||||
productName: v.productCode ?? "",
|
||||
productNature: SupermarketNature.values.fromCode(v.productNature) ??
|
||||
SupermarketNature.DEFAULT,
|
||||
productNature: ProductNature.values.fromCode(v.productNature) ??
|
||||
ProductNature.DEFAULT,
|
||||
barCode: "",
|
||||
packageNum: 0,
|
||||
unit: v.productCode ?? "",
|
||||
|
||||
@@ -12,7 +12,7 @@ import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
mixin OrderMixin {
|
||||
static const _tag = "OrderMixin";
|
||||
|
||||
final appController = Get.find<AppControl>();
|
||||
final appC = Get.find<AppControl>();
|
||||
|
||||
/// **************** start 需要重制 start ****************
|
||||
|
||||
@@ -28,10 +28,10 @@ mixin OrderMixin {
|
||||
RxList<ClassifyEntity> classifyList = RxList([]);
|
||||
|
||||
// 食堂商品
|
||||
RxList<CanteenSpuEntity> canteenSpuDao = RxList([]);
|
||||
RxList<CanteenSpuEntity> canteenSpuList = RxList([]);
|
||||
|
||||
// 超市商品
|
||||
RxList<SupermarketSpuEntity> supermarketSpuDao = RxList([]);
|
||||
RxList<SupermarketSpuEntity> supermarketSpuList = RxList([]);
|
||||
|
||||
// 总价
|
||||
RxInt totalPrice = RxInt(0);
|
||||
@@ -65,6 +65,10 @@ mixin OrderMixin {
|
||||
// 本地订单id
|
||||
int? sqlOrderId;
|
||||
|
||||
RxInt currentPage = RxInt(1);
|
||||
RxInt totalPage = RxInt(0);
|
||||
RxInt pageSize = RxInt(18);
|
||||
|
||||
Future? putOffSendSubScreenDelayed;
|
||||
|
||||
/// **************** start 更新属性 start ****************
|
||||
@@ -92,7 +96,7 @@ mixin OrderMixin {
|
||||
|
||||
// 获取分类
|
||||
Future<void> getClassify() async {
|
||||
final list = await appController.dataBase.getClassifyDao.getAll(
|
||||
final list = await appC.dataBase.getClassifyDao.getAll(
|
||||
_sysType.name,
|
||||
hourType.value.code,
|
||||
);
|
||||
@@ -116,18 +120,23 @@ mixin OrderMixin {
|
||||
// 获取商品
|
||||
Future<void> getProduct({String classifyCode = "-1"}) async {
|
||||
if (_sysType == SysType.SUPERMARKET) {
|
||||
final list = await appController.dataBase.getSupermarketSpuDao.getAll(
|
||||
final supermarketSkuDao = appC.dataBase.getSupermarketSkuDao;
|
||||
final total = await supermarketSkuDao.getCount();
|
||||
totalPage.value = total ?? 0;
|
||||
final list = await supermarketSkuDao.getAllPage(
|
||||
classifyCode,
|
||||
pageSize.value,
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
);
|
||||
supermarketSpuDao.value = list;
|
||||
supermarketSpuDao.refresh();
|
||||
supermarketSpuList.value = list;
|
||||
supermarketSpuList.refresh();
|
||||
} else if (_sysType == SysType.CANTEEN) {
|
||||
final list = await appController.dataBase.getCanteenSpuDao.getAll(
|
||||
final list = await appC.dataBase.getCanteenSpuDao.getAll(
|
||||
classifyCode,
|
||||
hourType.value.code,
|
||||
);
|
||||
canteenSpuDao.value = list;
|
||||
canteenSpuDao.refresh();
|
||||
canteenSpuList.value = list;
|
||||
canteenSpuList.refresh();
|
||||
}
|
||||
classifyList.refresh();
|
||||
}
|
||||
@@ -156,7 +165,7 @@ mixin OrderMixin {
|
||||
weight: getProductWeight(),
|
||||
createTime: DateTime.now(),
|
||||
);
|
||||
final id = await appController.dataBase.getOrderDao.save(order);
|
||||
final id = await appC.dataBase.getOrderDao.save(order);
|
||||
if (id == null) {
|
||||
logger.e("|$_tag|创建本地订单,创建父订单错误");
|
||||
return null;
|
||||
@@ -176,7 +185,7 @@ mixin OrderMixin {
|
||||
logger.e("|$_tag|创建本地购物车,失败本地订单id不存在");
|
||||
return false;
|
||||
}
|
||||
final orderDao = appController.dataBase.getOrderDao;
|
||||
final orderDao = appC.dataBase.getOrderDao;
|
||||
final sqlOrderDetail = await orderDao.findById(sqlOrderId!);
|
||||
if (ObjectUtil.isEmpty(sqlOrderDetail)) {
|
||||
logger.e("|$_tag|创建本地购物车,失败本地订单不存在,sqlOrderDetail:|$sqlOrderDetail|;");
|
||||
@@ -188,7 +197,7 @@ mixin OrderMixin {
|
||||
e.productWidget = double.parse(e.productWidget.toStringAsFixed(2));
|
||||
return e;
|
||||
}).toList();
|
||||
await appController.dataBase.getShopCardDao.batchSave(cardList);
|
||||
await appC.dataBase.getShopCardDao.batchSave(cardList);
|
||||
return true;
|
||||
} catch (e) {
|
||||
logger.i("|$_tag|创建本地购物车,失败orderId:|$sqlOrderId|;error:|$e|");
|
||||
@@ -202,7 +211,7 @@ mixin OrderMixin {
|
||||
logger.e("|$_tag|更新本地订单,失败本地订单id不存在");
|
||||
return false;
|
||||
}
|
||||
final orderDao = appController.dataBase.getOrderDao;
|
||||
final orderDao = appC.dataBase.getOrderDao;
|
||||
final sqlOrderDetail = await orderDao.findById(sqlOrderId!);
|
||||
if (ObjectUtil.isEmpty(sqlOrderDetail)) {
|
||||
logger.e("|$_tag|更新本地订单,失败本地订单不存在,sqlOrderDetail:|$sqlOrderDetail|;");
|
||||
@@ -248,7 +257,7 @@ mixin OrderMixin {
|
||||
Toast.error(msg: "创建订单失败,本地订单id不存在");
|
||||
return;
|
||||
}
|
||||
final orderDao = appController.dataBase.getOrderDao;
|
||||
final orderDao = appC.dataBase.getOrderDao;
|
||||
final sqlOrderDetail = await orderDao.findById(sqlOrderId!);
|
||||
if (ObjectUtil.isEmpty(sqlOrderDetail)) {
|
||||
logger.e("|$_tag|开始创建api订单,失败本地订单不存在,sqlOrderDetail:|$sqlOrderDetail|");
|
||||
|
||||
@@ -11,6 +11,9 @@ Widget orderAllPrice(
|
||||
BuildContext context, {
|
||||
required num totalPrice,
|
||||
required num amountMealPrice,
|
||||
String productPrice = "菜品总价",
|
||||
bool visibleProductPrice = true,
|
||||
bool visibleAmountMealPrice = true,
|
||||
}) {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
@@ -22,18 +25,18 @@ Widget orderAllPrice(
|
||||
),
|
||||
<Widget>[
|
||||
Text(
|
||||
"菜品总价",
|
||||
productPrice,
|
||||
style: theme.typography.lg,
|
||||
),
|
||||
appPrice(context, totalPrice),
|
||||
].toRow(),
|
||||
].toRow().offstage(offstage: !visibleProductPrice),
|
||||
<Widget>[
|
||||
Text(
|
||||
"额外支付",
|
||||
style: theme.typography.lg,
|
||||
),
|
||||
appPrice(context, amountMealPrice),
|
||||
].toRow(),
|
||||
].toRow().offstage(offstage: !visibleAmountMealPrice),
|
||||
<Widget>[
|
||||
Text(
|
||||
"实际扣款",
|
||||
@@ -56,12 +59,14 @@ Widget orderAllPrice(
|
||||
/// 商品选择面板
|
||||
Widget orderSelectPanel(
|
||||
BuildContext context, {
|
||||
required void Function(int, int) onChange,
|
||||
void Function(int, int)? onChange,
|
||||
String label = "",
|
||||
int total = 1,
|
||||
num price = 0,
|
||||
int index = 0,
|
||||
double height = 50,
|
||||
showPlus = false,
|
||||
showWidget = false,
|
||||
}) {
|
||||
final theme = FTheme.of(context);
|
||||
return LayoutBuilder(
|
||||
@@ -86,7 +91,9 @@ Widget orderSelectPanel(
|
||||
.decorated(color: theme.colorScheme.primary)
|
||||
.onTap(() {
|
||||
if (total < 100) {
|
||||
onChange(total + 1, index);
|
||||
if (onChange != null) {
|
||||
onChange(total + 1, index);
|
||||
}
|
||||
}
|
||||
}),
|
||||
Text(
|
||||
@@ -105,10 +112,15 @@ Widget orderSelectPanel(
|
||||
.decorated(color: theme.colorScheme.error)
|
||||
.onTap(() {
|
||||
if (total > 0) {
|
||||
onChange(total - 1, index);
|
||||
if (onChange != null) {
|
||||
onChange(total - 1, index);
|
||||
}
|
||||
}
|
||||
}),
|
||||
].toRow(mainAxisAlignment: MainAxisAlignment.end).expanded(),
|
||||
]
|
||||
.toRow(mainAxisAlignment: MainAxisAlignment.end)
|
||||
.expanded()
|
||||
.offstage(offstage: !showPlus),
|
||||
]
|
||||
.toRow(mainAxisAlignment: MainAxisAlignment.center)
|
||||
.height(height.h)
|
||||
|
||||
@@ -132,6 +132,7 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
productName: current.name,
|
||||
productPic: current.image ?? "",
|
||||
productPrice: current.price,
|
||||
nature: ProductNature.DEFAULT,
|
||||
productNumber: 1,
|
||||
productWidget: 0,
|
||||
totalPrice: current.price,
|
||||
@@ -261,6 +262,7 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
productName: v.name,
|
||||
productPic: v.image ?? "",
|
||||
productPrice: v.price,
|
||||
nature: ProductNature.DEFAULT,
|
||||
productNumber: 1,
|
||||
productWidget: 0,
|
||||
totalPrice: v.price,
|
||||
|
||||
@@ -60,13 +60,13 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
itemCount: controller.classifyList.length,
|
||||
itemBuilder: (context, index) {
|
||||
if (ObjectUtil.isEmpty(controller.classifyList) ||
|
||||
ObjectUtil.isEmpty(controller.canteenSpuDao)) {
|
||||
ObjectUtil.isEmpty(controller.canteenSpuList)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final current = controller.classifyList[index].serviceUniqueCode;
|
||||
final currentStr = controller.classifyList
|
||||
.firstWhereOrNull((v) => v.serviceUniqueCode == current);
|
||||
final currentList = controller.canteenSpuDao
|
||||
final currentList = controller.canteenSpuList
|
||||
.where((i) => i.classifyServiceUniqueCode == current)
|
||||
.toList();
|
||||
if (ObjectUtil.isEmpty(currentList)) {
|
||||
@@ -96,23 +96,22 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
}) {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
ObjectUtil.isNotEmpty(title)
|
||||
? Text(
|
||||
title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.typography.lg.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
)
|
||||
.center()
|
||||
.width(double.infinity)
|
||||
.padding(vertical: 1.h)
|
||||
.decorated(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
borderRadius: theme.style.borderRadius / 2,
|
||||
)
|
||||
.marginOnly(bottom: 20.h)
|
||||
: const SizedBox.shrink(),
|
||||
Text(
|
||||
title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.typography.lg.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
)
|
||||
.center()
|
||||
.width(double.infinity)
|
||||
.padding(vertical: 1.h)
|
||||
.decorated(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
borderRadius: theme.style.borderRadius / 2,
|
||||
)
|
||||
.marginOnly(bottom: 20.h)
|
||||
.offstage(offstage: ObjectUtil.isEmpty(title)),
|
||||
productList
|
||||
.map(
|
||||
(v) => orderCaneenSpuCard(
|
||||
@@ -175,6 +174,7 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
price: current.productPrice,
|
||||
total: current.productNumber,
|
||||
index: index,
|
||||
showPlus: true,
|
||||
onChange: (number, i) =>
|
||||
controller.doComputedInputChange(number, i),
|
||||
).marginOnly(bottom: 10.h);
|
||||
|
||||
@@ -17,10 +17,6 @@ class SupermarketOrderController extends GetxController with OrderMixin {
|
||||
|
||||
late SysSetting appSetting;
|
||||
|
||||
RxInt currentPage = RxInt(1);
|
||||
RxInt totalPage = RxInt(0);
|
||||
RxInt pageSize = RxInt(24);
|
||||
|
||||
_initData() {
|
||||
update(["supermarket_order"]);
|
||||
}
|
||||
@@ -89,6 +85,53 @@ class SupermarketOrderController extends GetxController with OrderMixin {
|
||||
if (page != null) currentPage.value = page;
|
||||
}
|
||||
|
||||
// 点击商品
|
||||
void doProduct(SupermarketSpuEntity current) async {
|
||||
final target = shopCardList.firstWhereOrNull((e) {
|
||||
return e.productServiceUniqueCode == current.serviceUniqueCode;
|
||||
});
|
||||
if (ObjectUtil.isEmpty(target)) {
|
||||
final data = ShopCardEntity(
|
||||
orderId: -1,
|
||||
productServiceUniqueCode: current.serviceUniqueCode,
|
||||
productName: current.productName,
|
||||
productPic: current.picUrl ?? "",
|
||||
productPrice: current.retailPrice,
|
||||
nature: current.productNature,
|
||||
productNumber: 1,
|
||||
productWidget: 0,
|
||||
totalPrice: current.retailPrice,
|
||||
);
|
||||
shopCardList.add(data);
|
||||
} else {
|
||||
// 旧商品
|
||||
target!.productNumber += 1;
|
||||
target.totalPrice = _computedProductTotalPrice(
|
||||
target.productPrice,
|
||||
target.productNumber,
|
||||
);
|
||||
}
|
||||
computedTotalPrice();
|
||||
sendSubScreen();
|
||||
}
|
||||
|
||||
// |+|或者|-|点击更改商品数量
|
||||
void doComputedInputChange(int number, int index) async {
|
||||
final current = shopCardList[index];
|
||||
current.productNumber = number;
|
||||
current.totalPrice = _computedProductTotalPrice(
|
||||
current.productPrice,
|
||||
current.productNumber,
|
||||
);
|
||||
if (current.productNumber == 0) {
|
||||
shopCardList.removeWhere((e) {
|
||||
return e.productServiceUniqueCode == current.productServiceUniqueCode;
|
||||
});
|
||||
}
|
||||
computedTotalPrice();
|
||||
sendSubScreen();
|
||||
}
|
||||
|
||||
void _listenPayTypeSelectCallback() {
|
||||
final payTypeSelect = Get.find<SelectPayTypeDialogController>();
|
||||
// |支付方式|点击|开始识别|
|
||||
@@ -123,8 +166,6 @@ class SupermarketOrderController extends GetxController with OrderMixin {
|
||||
status: '支付中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
// 最后计算一次额外的价格
|
||||
await _computedAmountMealPrice();
|
||||
await updateSqlOrder();
|
||||
await createApiOrder();
|
||||
_clearShopCard();
|
||||
@@ -134,17 +175,6 @@ class SupermarketOrderController extends GetxController with OrderMixin {
|
||||
payTypeSelect.onCancel = () {};
|
||||
}
|
||||
|
||||
// 计算额外的价格
|
||||
Future<void> _computedAmountMealPrice() async {
|
||||
final price = await getAmountMealPrice(
|
||||
price: totalPrice.value,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(price)) {
|
||||
amountMealPrice.value = int.parse(price!.toString());
|
||||
sendSubScreen();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _clearShopCard() async {
|
||||
shopCardList.clear();
|
||||
payUser.value = null;
|
||||
@@ -181,4 +211,9 @@ class SupermarketOrderController extends GetxController with OrderMixin {
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
// 计算单个的价格
|
||||
int _computedProductTotalPrice(int price, int number) {
|
||||
return price * number;
|
||||
}
|
||||
}
|
||||
@@ -77,12 +77,46 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
|
||||
Widget _buildProductItem(
|
||||
BuildContext context, {
|
||||
required List<CanteenSpuEntity> productList,
|
||||
required List<SupermarketSpuEntity> productList,
|
||||
required double productSpacing,
|
||||
required Size productSize,
|
||||
String? title = "",
|
||||
}) {
|
||||
return <Widget>[].toColumn();
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
Text(
|
||||
title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.typography.lg.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
)
|
||||
.center()
|
||||
.width(double.infinity)
|
||||
.padding(vertical: 1.h)
|
||||
.decorated(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
borderRadius: theme.style.borderRadius / 2,
|
||||
)
|
||||
.marginOnly(bottom: 20.h)
|
||||
.offstage(offstage: ObjectUtil.isEmpty(title)),
|
||||
productList
|
||||
.map(
|
||||
(v) => orderSupermarketSpuCard(context, supermarketSpu: v)
|
||||
.width(productSize.width)
|
||||
.height(productSize.height)
|
||||
.onTap(() => controller.doProduct(v)),
|
||||
)
|
||||
.toList()
|
||||
.toWrap(
|
||||
spacing: productSpacing,
|
||||
runSpacing: productSpacing,
|
||||
)
|
||||
.marginOnly(bottom: 20.h),
|
||||
].toColumn(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProduct() {
|
||||
@@ -92,20 +126,20 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
const runSpacing = 10;
|
||||
double maxHeight = constraints.maxHeight;
|
||||
double maxWidth = constraints.maxWidth;
|
||||
double itemWidth = (maxWidth - spacing * 5) / 6;
|
||||
double itemHeight = (maxHeight - (runSpacing + 30) * 3) / 3;
|
||||
double itemWidth = (maxWidth - spacing * 4) / 5;
|
||||
double itemHeight = (maxHeight - (runSpacing + 30) * 2) / 2;
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: controller.classifyList.length,
|
||||
itemBuilder: (context, index) {
|
||||
if (ObjectUtil.isEmpty(controller.classifyList) ||
|
||||
ObjectUtil.isEmpty(controller.canteenSpuDao)) {
|
||||
ObjectUtil.isEmpty(controller.supermarketSpuList)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final current = controller.classifyList[index].serviceUniqueCode;
|
||||
final currentStr = controller.classifyList
|
||||
.firstWhereOrNull((v) => v.serviceUniqueCode == current);
|
||||
final currentList = controller.canteenSpuDao
|
||||
final currentList = controller.supermarketSpuList
|
||||
.where((i) => i.classifyServiceUniqueCode == current)
|
||||
.toList();
|
||||
if (ObjectUtil.isEmpty(currentList)) {
|
||||
@@ -124,10 +158,17 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProductArea() {
|
||||
final context = Get.context!;
|
||||
Widget _buildProductArea(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
_buildProduct().expanded(),
|
||||
FDivider(
|
||||
style: theme.dividerStyles.verticalStyle.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Obx(
|
||||
() => appPage(
|
||||
context,
|
||||
@@ -173,13 +214,33 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
style: theme.typography.xl2,
|
||||
).alignLeft(),
|
||||
].toColumn(),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: controller.shopCardList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final current = controller.shopCardList[index];
|
||||
return orderSelectPanel(
|
||||
Get.context!,
|
||||
label: current.productName,
|
||||
price: current.productPrice,
|
||||
total: current.productNumber,
|
||||
index: index,
|
||||
showPlus: current.nature == ProductNature.DEFAULT,
|
||||
showWidget: current.nature == ProductNature.WEIGHT,
|
||||
onChange: (number, i) =>
|
||||
controller.doComputedInputChange(number, i),
|
||||
).marginOnly(bottom: 10.h);
|
||||
},
|
||||
),
|
||||
).expanded(),
|
||||
<Widget>[
|
||||
Obx(
|
||||
() => orderAllPrice(
|
||||
Get.context!,
|
||||
totalPrice: controller.totalPrice.value,
|
||||
amountMealPrice: controller.amountMealPrice.value,
|
||||
productPrice: "商品总价",
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
@@ -220,7 +281,7 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
SizedBox(width: 15.w),
|
||||
_buildProductArea().expanded(),
|
||||
_buildProductArea(context).expanded(),
|
||||
SizedBox(width: 15.w),
|
||||
_buildUser().width(width * 0.25).decorated(
|
||||
border: Border.all(
|
||||
|
||||
Reference in new issue
Block a user