feat:特色菜收费

This commit is contained in:
dzc committed 2026-03-29 16:45:54 +08:00
1 parent e5e24231e7
commit 3729e3b896
18 files changed
+93 -26

No files matched your search

@@ -15,7 +15,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_PATH = "pj_cashier/database";
private static final String DATABASE_NAME = "cash_register.db";
private static final int DATABASE_VERSION = 6;
private static final int DATABASE_VERSION = 7;
public DatabaseHelper(Context context) {
super(context, getCustomDatabasePath(context), null, DATABASE_VERSION);
+2 -2
View File
@@ -15,8 +15,8 @@ ServiceAppVersion _$ServiceAppVersionFromJson(Map<String, dynamic> json) =>
versionName: json['versionName'] as String?,
updateContent: json['updateContent'] as String?,
downloadUrl: json['downloadUrl'] as String?,
isForce: JsonTool.stringToBoolean(json['isForce'] as String),
isSilent: JsonTool.stringToBoolean(json['isSilent'] as String),
isForce: JsonTool.stringToBoolean(json['isForce'] as String?),
isSilent: JsonTool.stringToBoolean(json['isSilent'] as String?),
status: json['status'] as String?,
);
+2 -2
View File
@@ -159,7 +159,7 @@ ServiceOpenCard _$ServiceOpenCardFromJson(Map<String, dynamic> json) =>
cardNumber: json['cardNumber'] as String?,
walletId: json['walletId'] as String?,
isActiveHardware:
JsonTool.stringToBoolean(json['isActiveHardware'] as String),
JsonTool.stringToBoolean(json['isActiveHardware'] as String?),
);
Map<String, dynamic> _$ServiceOpenCardToJson(ServiceOpenCard instance) =>
@@ -269,7 +269,7 @@ ServiceBroadcastToday _$ServiceBroadcastTodayFromJson(
content: json['content'] as String,
broadcastCount: (json['broadcastCount'] as num?)?.toInt(),
broadcastMaxCount: (json['broadcastMaxCount'] as num?)?.toInt(),
isBroadcast: JsonTool.stringToBoolean(json['isBroadcast'] as String),
isBroadcast: JsonTool.stringToBoolean(json['isBroadcast'] as String?),
hourType: json['hourType'] as String?,
productDesc: json['productDesc'] as String,
payPrice: (json['payPrice'] as num).toInt(),
@@ -44,7 +44,7 @@ ServiceProduct _$ServiceProductFromJson(Map<String, dynamic> json) =>
)
..price = (json['price'] as num?)?.toInt()
..isPriceIncreased =
JsonTool.stringToBoolean(json['isPriceIncreased'] as String);
JsonTool.stringToBoolean(json['isPriceIncreased'] as String?);
Map<String, dynamic> _$ServiceProductToJson(ServiceProduct instance) =>
<String, dynamic>{
+1 -1
View File
@@ -16,7 +16,7 @@ ServiceUser _$ServiceUserFromJson(Map<String, dynamic> json) => ServiceUser(
walletTypeId: json['walletTypeId'] as String?,
walletBalance: (json['walletBalance'] as num?)?.toInt(),
walletIsFreeze:
JsonTool.stringToBoolean(json['walletIsFreeze'] as String),
JsonTool.stringToBoolean(json['walletIsFreeze'] as String?),
walletCardNumber: json['walletCardNumber'] as String?,
canteenId: json['canteenId'] as String?,
);
@@ -10,16 +10,16 @@ ServicePaySetting _$ServicePaySettingFromJson(Map<String, dynamic> json) =>
ServicePaySetting(
id: json['id'] as String?,
payAmountEnable:
JsonTool.stringToBoolean(json['payAmountEnable'] as String),
JsonTool.stringToBoolean(json['payAmountEnable'] as String?),
payAmountMealLimit: (json['payAmountMealLimit'] as num?)?.toInt(),
payAmountMealTimes: (json['payAmountMealTimes'] as num?)?.toDouble(),
afterSaleRefundReasons: json['afterSaleRefundReasons'] as String?,
afterSaleReturnReasons: json['afterSaleReturnReasons'] as String?,
refreshQrCodeEnable:
JsonTool.stringToBoolean(json['refreshQrCodeEnable'] as String),
JsonTool.stringToBoolean(json['refreshQrCodeEnable'] as String?),
refreshQrCodeFre: (json['refreshQrCodeFre'] as num?)?.toInt(),
offLineOrderApplyEnable:
JsonTool.stringToBoolean(json['offLineOrderApplyEnable'] as String),
JsonTool.stringToBoolean(json['offLineOrderApplyEnable'] as String?),
);
Map<String, dynamic> _$ServicePaySettingToJson(ServicePaySetting instance) =>
@@ -67,7 +67,7 @@ ServiceWallet _$ServiceWalletFromJson(Map<String, dynamic> json) =>
walletTypeId: json['walletTypeId'] as String,
balance: (json['balance'] as num).toInt(),
cardNumber: json['cardNumber'] as String?,
isFreeze: JsonTool.stringToBoolean(json['isFreeze'] as String),
isFreeze: JsonTool.stringToBoolean(json['isFreeze'] as String?),
);
Map<String, dynamic> _$ServiceWalletToJson(ServiceWallet instance) =>
+1 -1
View File
@@ -63,7 +63,7 @@ MqttTakeFoodBroadcastMsg _$MqttTakeFoodBroadcastMsgFromJson(
productDesc: json['productDesc'] as String,
payPrice: (json['payPrice'] as num).toInt(),
hourType: json['hourType'] as String,
isDone: JsonTool.stringToBoolean(json['isDone'] as String),
isDone: JsonTool.stringToBoolean(json['isDone'] as String?),
);
Map<String, dynamic> _$MqttTakeFoodBroadcastMsgToJson(
+1 -1
View File
@@ -40,7 +40,7 @@ const typeConverters = <Type>[
BoolConverter,
];
@Database(version: 6, entities: entities)
@Database(version: 7, entities: entities)
@TypeConverters(typeConverters)
abstract class AppDatabase extends FloorDatabase {
BroadcastDao get getBroadcastDao;
+14 -6
View File
@@ -104,7 +104,7 @@ class _$AppDatabase extends AppDatabase {
Callback? callback,
]) async {
final databaseOptions = sqflite.OpenDatabaseOptions(
version: 5,
version: 7,
onConfigure: (database) async {
await database.execute('PRAGMA foreign_keys = ON');
await callback?.onConfigure?.call(database);
@@ -134,7 +134,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, `nature` TEXT 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, `isPriceIncreased` 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(
@@ -1164,7 +1164,9 @@ class _$ShopCardDao extends ShopCardDao {
'nature': _supermarketNatureConverter.encode(item.nature),
'productNumber': item.productNumber,
'productWidget': item.productWidget,
'totalPrice': item.totalPrice
'totalPrice': item.totalPrice,
'isPriceIncreased':
_boolConverter.encode(item.isPriceIncreased)
}),
_shopCardEntityUpdateAdapter = UpdateAdapter(
database,
@@ -1180,7 +1182,9 @@ class _$ShopCardDao extends ShopCardDao {
'nature': _supermarketNatureConverter.encode(item.nature),
'productNumber': item.productNumber,
'productWidget': item.productWidget,
'totalPrice': item.totalPrice
'totalPrice': item.totalPrice,
'isPriceIncreased':
_boolConverter.encode(item.isPriceIncreased)
}),
_shopCardEntityDeletionAdapter = DeletionAdapter(
database,
@@ -1196,7 +1200,9 @@ class _$ShopCardDao extends ShopCardDao {
'nature': _supermarketNatureConverter.encode(item.nature),
'productNumber': item.productNumber,
'productWidget': item.productWidget,
'totalPrice': item.totalPrice
'totalPrice': item.totalPrice,
'isPriceIncreased':
_boolConverter.encode(item.isPriceIncreased)
});
final sqflite.DatabaseExecutor database;
@@ -1225,7 +1231,9 @@ class _$ShopCardDao extends ShopCardDao {
nature: _supermarketNatureConverter.decode(row['nature'] as String),
productNumber: row['productNumber'] as int,
productWidget: row['productWidget'] as double,
totalPrice: row['totalPrice'] as int),
totalPrice: row['totalPrice'] as int,
isPriceIncreased:
_boolConverter.decode(row['isPriceIncreased'] as int)),
arguments: [orderId]);
}
@@ -167,13 +167,30 @@ abstract class DatabaseMigration {
}
});
static Migration migration6To7 = Migration(6, 7, (database) async {
final columns = await database.rawQuery("PRAGMA table_info(shop_card)");
bool hasIsPriceIncreased = false;
for (final c in columns) {
if (c['name'] == 'isPriceIncreased') {
hasIsPriceIncreased = true;
break;
}
}
if (!hasIsPriceIncreased) {
await database.execute(
"ALTER TABLE shop_card ADD COLUMN isPriceIncreased INTEGER NOT NULL DEFAULT 0",
);
}
});
static List<Migration> getDatabaseMigrations() {
return [
migration1To2,
migration2To3,
migration3To4,
migration4To5,
migration5To6
migration5To6,
migration6To7,
];
}
}
@@ -38,6 +38,9 @@ class ShopCardEntity {
/// 单商品总价(分)
int totalPrice;
/// 是否涨价
bool isPriceIncreased;
ShopCardEntity({
this.id,
required this.orderId,
@@ -49,6 +52,7 @@ class ShopCardEntity {
required this.productNumber,
required this.productWidget,
required this.totalPrice,
required this.isPriceIncreased,
});
factory ShopCardEntity.fromJson(Map<String, dynamic> json) =>
@@ -18,6 +18,7 @@ ShopCardEntity _$ShopCardEntityFromJson(Map<String, dynamic> json) =>
productNumber: (json['productNumber'] as num).toInt(),
productWidget: (json['productWidget'] as num).toDouble(),
totalPrice: (json['totalPrice'] as num).toInt(),
isPriceIncreased: json['isPriceIncreased'] as bool,
);
Map<String, dynamic> _$ShopCardEntityToJson(ShopCardEntity instance) =>
@@ -32,6 +33,7 @@ Map<String, dynamic> _$ShopCardEntityToJson(ShopCardEntity instance) =>
'productNumber': instance.productNumber,
'productWidget': instance.productWidget,
'totalPrice': instance.totalPrice,
'isPriceIncreased': instance.isPriceIncreased,
};
const _$ProductNatureEnumMap = {
@@ -3,7 +3,6 @@ import 'package:equatable/equatable.dart';
import 'package:floor/floor.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import 'package:pj_supermarket_cloud/common/models/index.dart';
part 'user_entity.g.dart';
@@ -30,6 +29,13 @@ class DiscountsItem {
/// 基础金额(分),超过了这个基数`extraPer`就生效
int basePrice;
/// 特色菜是否额外收费
@JsonKey(
fromJson: JsonTool.stringToBoolean,
toJson: JsonTool.booleanToString,
)
bool specialDishEnable;
/// 打折(8折->0.8)
double? extraPer;
@@ -38,6 +44,7 @@ class DiscountsItem {
required this.hourType,
required this.type,
required this.basePrice,
required this.specialDishEnable,
required this.extraPer,
});
@@ -12,6 +12,8 @@ DiscountsItem _$DiscountsItemFromJson(Map<String, dynamic> json) =>
hourType: JsonTool.stringToProductHourType(json['hourType'] as String?),
type: JsonTool.stringToDiscountsType(json['type'] as String?),
basePrice: (json['basePrice'] as num).toInt(),
specialDishEnable:
JsonTool.stringToBoolean(json['specialDishEnable'] as String?),
extraPer: (json['extraPer'] as num?)?.toDouble(),
);
@@ -21,6 +23,7 @@ Map<String, dynamic> _$DiscountsItemToJson(DiscountsItem instance) =>
'hourType': JsonTool.productHourTypeToString(instance.hourType),
'type': JsonTool.discountsTypeToString(instance.type),
'basePrice': instance.basePrice,
'specialDishEnable': JsonTool.booleanToString(instance.specialDishEnable),
'extraPer': instance.extraPer,
};
+24 -3
View File
@@ -30,12 +30,13 @@ class DiscountsTool {
}
/// 计算额外增加的金额
/// [totalPrice] 总金额(分)
/// [discountsItem] 优惠项
/// [userId] 用户id
/// [shopCardList] 购物车列表
/// [hourType] 优惠类型
/// [return] 额外增加的金额(分)
static Future<int> computedExtraPrice({
required String userId,
required int totalPrice,
required List<ShopCardEntity> shopCardList,
required String hourType,
}) async {
var discountsItems = await updateUserDiscountsList(userId: userId);
@@ -43,10 +44,30 @@ class DiscountsTool {
?.where((element) => element.hourType?.code == hourType)
.toList();
if (ObjectUtil.isEmpty(discountsItems)) return 0;
/// 计算额外价格
var extraPrice = 0;
for (final item in discountsItems!) {
final extraPer = item.extraPer;
final specialDishEnable = item.specialDishEnable;
if (extraPer == null || extraPer <= 1.0) continue;
// 计算总价
int totalPrice = 0;
// 特色菜不额外收费
if (!specialDishEnable) {
totalPrice = shopCardList
.where((item) => item.isPriceIncreased)
.map((item) => item.totalPrice)
.reduce((value, element) => value + element);
extraPrice += item.computedDiscountsExtraPrice(totalPrice);
}
// 特色菜额外收费
if (specialDishEnable) {
totalPrice = shopCardList
.map((item) => item.totalPrice)
.reduce((value, element) => value + element);
extraPrice += item.computedDiscountsExtraPrice(totalPrice);
}
extraPrice += item.computedDiscountsExtraPrice(totalPrice);
}
return extraPrice;
+2 -1
View File
@@ -1,7 +1,8 @@
import 'package:pj_supermarket_cloud/common/index.dart';
abstract class JsonTool {
static bool stringToBoolean(String value) {
static bool stringToBoolean(String? value) {
if (value == null) return false;
return value == '1';
}
+3 -1
View File
@@ -172,6 +172,7 @@ class CanteenProductController extends GetxController with OrderMixin {
productNumber: 1,
productWidget: 0,
totalPrice: current.price,
isPriceIncreased: current.isPriceIncreased,
);
shopCardList.add(data);
} else {
@@ -277,7 +278,7 @@ class CanteenProductController extends GetxController with OrderMixin {
ObjectUtil.isNotEmpty(hourType.value)) {
extraPrice = await DiscountsTool.computedExtraPrice(
userId: payUser.value?.userId ?? "",
totalPrice: totalPrice.value,
shopCardList: shopCardList,
hourType: hourType.value.code,
);
}
@@ -316,6 +317,7 @@ class CanteenProductController extends GetxController with OrderMixin {
productNumber: 1,
productWidget: 0,
totalPrice: v.price,
isPriceIncreased: v.isPriceIncreased,
);
shopCardList.add(data);
}
@@ -215,6 +215,8 @@ class SupermarketOrderController extends GetxController with OrderMixin {
productNumber: current.productNature == ProductNature.WEIGHT ? 0 : 1,
productWidget: 0,
totalPrice: currentPrice,
// todo 超市暂时用不到这个字段
isPriceIncreased: false,
);
if (data.nature == ProductNature.WEIGHT) {
data.totalPrice = 0;