feat:额外收费
This commit is contained in:
1 parent
2b956342f4
commit
e730b6923c
17 files changed
+461
-153
No files matched your search
@@ -4,7 +4,7 @@
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "8495dee1fd4aacbe9de707e7581203232f591b2f"
|
||||
revision: "d8a9f9a52e5af486f80d932e838ee93861ffd863"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
@@ -13,17 +13,11 @@ project_type: app
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863
|
||||
base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863
|
||||
- platform: android
|
||||
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
- platform: ios
|
||||
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
- platform: macos
|
||||
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
|
||||
create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863
|
||||
base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863
|
||||
|
||||
# User provided section
|
||||
|
||||
|
||||
+1
-1
@@ -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 = 3;
|
||||
private static final int DATABASE_VERSION = 5;
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, getCustomDatabasePath(context), null, DATABASE_VERSION);
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
abstract class WalletApi {
|
||||
/// 优惠列表
|
||||
static Future<List<DiscountsItem>?> getDiscountsListByUserId(
|
||||
dynamic params,
|
||||
) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/wallet/wallet-setting/ad/get-discounts-list",
|
||||
queryParameters: params,
|
||||
);
|
||||
if (res.data == null) return null;
|
||||
return (res.data as List).map((e) => DiscountsItem.fromJson(e)).toList();
|
||||
}
|
||||
|
||||
/// 支付配置
|
||||
static Future<ServicePaySetting?> getPaySetting() async {
|
||||
final res = await HttpManage().dio.get(
|
||||
|
||||
@@ -183,3 +183,16 @@ enum ProductNature implements BaseEnum {
|
||||
|
||||
const ProductNature(this.code, this.title);
|
||||
}
|
||||
|
||||
/// 优惠类型
|
||||
enum DiscountsType implements BaseEnum {
|
||||
JZ_DISCOUNT("1", "9折优惠"),
|
||||
;
|
||||
|
||||
@override
|
||||
final String code;
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const DiscountsType(this.code, this.title);
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:floor/floor.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
import 'package:pj_supermarket_cloud/common/services/database/databaseMigration.dart';
|
||||
|
||||
import 'package:sqflite/sqflite.dart' as sqflite;
|
||||
|
||||
@@ -32,11 +34,13 @@ const typeConverters = <Type>[
|
||||
SysTypeConverter,
|
||||
PrintStatusConverter,
|
||||
SupermarketNatureConverter,
|
||||
DiscountsTypeConverter,
|
||||
ListDiscountsConverter,
|
||||
ListIntConverter,
|
||||
BoolConverter,
|
||||
];
|
||||
|
||||
@Database(version: 3, entities: entities)
|
||||
@Database(version: 5, entities: entities)
|
||||
@TypeConverters(typeConverters)
|
||||
abstract class AppDatabase extends FloorDatabase {
|
||||
BroadcastDao get getBroadcastDao;
|
||||
@@ -53,130 +57,11 @@ abstract class AppDatabase extends FloorDatabase {
|
||||
FaceDao get getFaceDao;
|
||||
SettingDao get getSettingDao;
|
||||
|
||||
// 获取数据库迁移列表
|
||||
static List<Migration> _getDatabaseMigrations() {
|
||||
return [
|
||||
// 从版本1到版本2的迁移:添加productNamePy字段
|
||||
Migration(1, 2, (database) async {
|
||||
// 先检查列是否存在,不存在才添加
|
||||
final result = await database.rawQuery(
|
||||
"PRAGMA table_info(supermarket_spu)",
|
||||
);
|
||||
bool columnExists = false;
|
||||
for (var column in result) {
|
||||
if (column['name'] == 'productNamePy') {
|
||||
columnExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!columnExists) {
|
||||
await database.execute(
|
||||
'ALTER TABLE supermarket_spu ADD COLUMN productNamePy TEXT');
|
||||
}
|
||||
}),
|
||||
Migration(2, 3, (database) async {
|
||||
// 如果表不存在则创建,存在则校验列并补齐缺失项
|
||||
final tables = await database.rawQuery(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='order_hold_bill'",
|
||||
);
|
||||
if (tables.isEmpty) {
|
||||
await database.execute('''
|
||||
CREATE TABLE IF NOT EXISTS order_hold_bill (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sysType TEXT NOT NULL,
|
||||
carListJson TEXT,
|
||||
userJson TEXT,
|
||||
price INTEGER DEFAULT 0 NOT NULL,
|
||||
extraPrice INTEGER DEFAULT 0 NOT NULL,
|
||||
payPrice INTEGER DEFAULT 0 NOT NULL,
|
||||
createTime TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_sysType ON order_hold_bill(sysType)",
|
||||
);
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_createTime ON order_hold_bill(createTime)",
|
||||
);
|
||||
} else {
|
||||
final columns =
|
||||
await database.rawQuery("PRAGMA table_info(order_hold_bill)");
|
||||
bool hasSysType = false;
|
||||
bool hasCarListJson = false;
|
||||
bool hasOrderListJson = false;
|
||||
bool hasUserJson = false;
|
||||
bool hasPrice = false;
|
||||
bool hasExtraPrice = false;
|
||||
bool hasPayPrice = false;
|
||||
bool hasCreateTime = false;
|
||||
for (final c in columns) {
|
||||
final name = c['name'];
|
||||
if (name == 'sysType') hasSysType = true;
|
||||
if (name == 'carListJson') hasCarListJson = true;
|
||||
if (name == 'orderListJson') hasOrderListJson = true;
|
||||
if (name == 'userJson') hasUserJson = true;
|
||||
if (name == 'price') hasPrice = true;
|
||||
if (name == 'extraPrice') hasExtraPrice = true;
|
||||
if (name == 'payPrice') hasPayPrice = true;
|
||||
if (name == 'createTime') hasCreateTime = true;
|
||||
}
|
||||
if (!hasSysType) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN sysType TEXT',
|
||||
);
|
||||
}
|
||||
if (!hasCarListJson) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN carListJson TEXT',
|
||||
);
|
||||
if (hasOrderListJson) {
|
||||
// 旧列迁移到新列
|
||||
await database.execute(
|
||||
"UPDATE order_hold_bill SET carListJson = orderListJson WHERE carListJson IS NULL",
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!hasUserJson) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN userJson TEXT',
|
||||
);
|
||||
}
|
||||
if (!hasPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN price INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasExtraPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN extraPrice INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasPayPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN payPrice INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasCreateTime) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN createTime TEXT DEFAULT "" NOT NULL',
|
||||
);
|
||||
}
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_sysType ON order_hold_bill(sysType)",
|
||||
);
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_createTime ON order_hold_bill(createTime)",
|
||||
);
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
static Future<AppDatabase> getDataBase() async {
|
||||
final dbPath = await AppFileTool.getDatabasePath();
|
||||
final name = "$dbPath/${Constants.databaseName}";
|
||||
final dataBase = await $FloorAppDatabase
|
||||
.databaseBuilder("$dbPath/${Constants.databaseName}")
|
||||
.databaseBuilder(name)
|
||||
.addCallback(
|
||||
Callback(
|
||||
onCreate: (database, version) async {
|
||||
@@ -190,7 +75,7 @@ abstract class AppDatabase extends FloorDatabase {
|
||||
},
|
||||
),
|
||||
)
|
||||
.addMigrations(_getDatabaseMigrations())
|
||||
.addMigrations(DatabaseMigration.getDatabaseMigrations())
|
||||
.build();
|
||||
return dataBase;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class _$AppDatabase extends AppDatabase {
|
||||
Callback? callback,
|
||||
]) async {
|
||||
final databaseOptions = sqflite.OpenDatabaseOptions(
|
||||
version: 3,
|
||||
version: 5,
|
||||
onConfigure: (database) async {
|
||||
await database.execute('PRAGMA foreign_keys = ON');
|
||||
await callback?.onConfigure?.call(database);
|
||||
@@ -140,7 +140,7 @@ class _$AppDatabase extends AppDatabase {
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `print_history` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `orderId` TEXT NOT NULL, `serviceOrderId` TEXT NOT NULL, `servicePrintId` TEXT NOT NULL, `invoiceUrl` TEXT NOT NULL, `status` TEXT NOT NULL, `printTime` TEXT, `syncTime` TEXT, `createTime` TEXT NOT NULL)');
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `user_record` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `userId` TEXT NOT NULL, `nickname` TEXT NOT NULL, `mobile` TEXT, `avatar` TEXT, `walletCardNumber` TEXT, `walletId` TEXT, `walletTypeId` TEXT, `walletBalance` INTEGER, `canteenId` TEXT, `createTime` TEXT, `updateTime` TEXT)');
|
||||
'CREATE TABLE IF NOT EXISTS `user_record` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `userId` TEXT NOT NULL, `nickname` TEXT NOT NULL, `mobile` TEXT, `avatar` TEXT, `walletCardNumber` TEXT, `walletId` TEXT, `walletTypeId` TEXT, `walletBalance` INTEGER, `canteenId` TEXT, `discountsList` TEXT, `discountsUpdateTime` TEXT, `createTime` TEXT, `updateTime` TEXT)');
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `face` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `userId` TEXT NOT NULL, `sampleId` TEXT NOT NULL, `userName` TEXT NOT NULL, `deptId` TEXT, `deptName` TEXT, `imagePath` TEXT NOT NULL, `path` TEXT, `faceModel` TEXT, `createTime` TEXT, `updateTime` TEXT)');
|
||||
await database.execute(
|
||||
@@ -1504,6 +1504,10 @@ class _$UserDao extends UserDao {
|
||||
'walletTypeId': item.walletTypeId,
|
||||
'walletBalance': item.walletBalance,
|
||||
'canteenId': item.canteenId,
|
||||
'discountsList':
|
||||
_listDiscountsConverter.encode(item.discountsList),
|
||||
'discountsUpdateTime':
|
||||
_dateTimeEmptyConverter.encode(item.discountsUpdateTime),
|
||||
'createTime': _dateTimeEmptyConverter.encode(item.createTime),
|
||||
'updateTime': _dateTimeEmptyConverter.encode(item.updateTime)
|
||||
}),
|
||||
@@ -1522,6 +1526,10 @@ class _$UserDao extends UserDao {
|
||||
'walletTypeId': item.walletTypeId,
|
||||
'walletBalance': item.walletBalance,
|
||||
'canteenId': item.canteenId,
|
||||
'discountsList':
|
||||
_listDiscountsConverter.encode(item.discountsList),
|
||||
'discountsUpdateTime':
|
||||
_dateTimeEmptyConverter.encode(item.discountsUpdateTime),
|
||||
'createTime': _dateTimeEmptyConverter.encode(item.createTime),
|
||||
'updateTime': _dateTimeEmptyConverter.encode(item.updateTime)
|
||||
}),
|
||||
@@ -1540,6 +1548,10 @@ class _$UserDao extends UserDao {
|
||||
'walletTypeId': item.walletTypeId,
|
||||
'walletBalance': item.walletBalance,
|
||||
'canteenId': item.canteenId,
|
||||
'discountsList':
|
||||
_listDiscountsConverter.encode(item.discountsList),
|
||||
'discountsUpdateTime':
|
||||
_dateTimeEmptyConverter.encode(item.discountsUpdateTime),
|
||||
'createTime': _dateTimeEmptyConverter.encode(item.createTime),
|
||||
'updateTime': _dateTimeEmptyConverter.encode(item.updateTime)
|
||||
});
|
||||
@@ -1946,5 +1958,7 @@ final _orderPayTypeConverter = OrderPayTypeConverter();
|
||||
final _sysTypeConverter = SysTypeConverter();
|
||||
final _printStatusConverter = PrintStatusConverter();
|
||||
final _supermarketNatureConverter = SupermarketNatureConverter();
|
||||
final _discountsTypeConverter = DiscountsTypeConverter();
|
||||
final _listDiscountsConverter = ListDiscountsConverter();
|
||||
final _listIntConverter = ListIntConverter();
|
||||
final _boolConverter = BoolConverter();
|
||||
@@ -0,0 +1,157 @@
|
||||
import 'package:floor/floor.dart';
|
||||
|
||||
abstract class DatabaseMigration {
|
||||
/// 从版本1到版本2的迁移:添加productNamePy字段
|
||||
static Migration migration1To2 = Migration(1, 2, (database) async {
|
||||
// 先检查列是否存在,不存在才添加
|
||||
final result = await database.rawQuery(
|
||||
"PRAGMA table_info(supermarket_spu)",
|
||||
);
|
||||
bool columnExists = false;
|
||||
for (var column in result) {
|
||||
if (column['name'] == 'productNamePy') {
|
||||
columnExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!columnExists) {
|
||||
await database
|
||||
.execute('ALTER TABLE supermarket_spu ADD COLUMN productNamePy TEXT');
|
||||
}
|
||||
});
|
||||
|
||||
/// 从版本2到版本3的迁移:添加orderListJson字段
|
||||
static Migration migration2To3 = Migration(2, 3, (database) async {
|
||||
// 如果表不存在则创建,存在则校验列并补齐缺失项
|
||||
final tables = await database.rawQuery(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='order_hold_bill'",
|
||||
);
|
||||
if (tables.isEmpty) {
|
||||
await database.execute('''
|
||||
CREATE TABLE IF NOT EXISTS order_hold_bill (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sysType TEXT NOT NULL,
|
||||
carListJson TEXT,
|
||||
userJson TEXT,
|
||||
price INTEGER DEFAULT 0 NOT NULL,
|
||||
extraPrice INTEGER DEFAULT 0 NOT NULL,
|
||||
payPrice INTEGER DEFAULT 0 NOT NULL,
|
||||
createTime TEXT NOT NULL
|
||||
)
|
||||
''');
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_sysType ON order_hold_bill(sysType)",
|
||||
);
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_createTime ON order_hold_bill(createTime)",
|
||||
);
|
||||
} else {
|
||||
final columns =
|
||||
await database.rawQuery("PRAGMA table_info(order_hold_bill)");
|
||||
bool hasSysType = false;
|
||||
bool hasCarListJson = false;
|
||||
bool hasOrderListJson = false;
|
||||
bool hasUserJson = false;
|
||||
bool hasPrice = false;
|
||||
bool hasExtraPrice = false;
|
||||
bool hasPayPrice = false;
|
||||
bool hasCreateTime = false;
|
||||
for (final c in columns) {
|
||||
final name = c['name'];
|
||||
if (name == 'sysType') hasSysType = true;
|
||||
if (name == 'carListJson') hasCarListJson = true;
|
||||
if (name == 'orderListJson') hasOrderListJson = true;
|
||||
if (name == 'userJson') hasUserJson = true;
|
||||
if (name == 'price') hasPrice = true;
|
||||
if (name == 'extraPrice') hasExtraPrice = true;
|
||||
if (name == 'payPrice') hasPayPrice = true;
|
||||
if (name == 'createTime') hasCreateTime = true;
|
||||
}
|
||||
if (!hasSysType) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN sysType TEXT',
|
||||
);
|
||||
}
|
||||
if (!hasCarListJson) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN carListJson TEXT',
|
||||
);
|
||||
if (hasOrderListJson) {
|
||||
// 旧列迁移到新列
|
||||
await database.execute(
|
||||
"UPDATE order_hold_bill SET carListJson = orderListJson WHERE carListJson IS NULL",
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!hasUserJson) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN userJson TEXT',
|
||||
);
|
||||
}
|
||||
if (!hasPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN price INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasExtraPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN extraPrice INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasPayPrice) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN payPrice INTEGER DEFAULT 0 NOT NULL',
|
||||
);
|
||||
}
|
||||
if (!hasCreateTime) {
|
||||
await database.execute(
|
||||
'ALTER TABLE order_hold_bill ADD COLUMN createTime TEXT DEFAULT "" NOT NULL',
|
||||
);
|
||||
}
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_sysType ON order_hold_bill(sysType)",
|
||||
);
|
||||
await database.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_order_hold_bill_createTime ON order_hold_bill(createTime)",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/// 从版本3到版本4的迁移:添加为user_record表添加discountsList字段
|
||||
static Migration migration3To4 = Migration(3, 4, (database) async {
|
||||
final columns = await database.rawQuery("PRAGMA table_info(user_record)");
|
||||
bool hasDiscountsList = false;
|
||||
for (final c in columns) {
|
||||
if (c['name'] == 'discountsList') {
|
||||
hasDiscountsList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasDiscountsList) {
|
||||
await database
|
||||
.execute("ALTER TABLE user_record ADD COLUMN discountsList TEXT");
|
||||
await database.execute(
|
||||
"UPDATE user_record SET discountsList = '[]' WHERE discountsList IS NULL",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
static Migration migration4To5 = Migration(4, 5, (database) async {
|
||||
final columns = await database.rawQuery("PRAGMA table_info(user_record)");
|
||||
bool hasDiscountsUpdateTime = false;
|
||||
for (final c in columns) {
|
||||
if (c['name'] == 'discountsUpdateTime') {
|
||||
hasDiscountsUpdateTime = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasDiscountsUpdateTime) {
|
||||
await database.execute(
|
||||
"ALTER TABLE user_record ADD COLUMN discountsUpdateTime TEXT");
|
||||
}
|
||||
});
|
||||
|
||||
static List<Migration> getDatabaseMigrations() {
|
||||
return [migration1To2, migration2To3, migration3To4];
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,62 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
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';
|
||||
|
||||
// 优惠
|
||||
@JsonSerializable()
|
||||
class DiscountsItem {
|
||||
/// 优惠活动名称
|
||||
String name;
|
||||
|
||||
/// 用餐时间段类型
|
||||
@JsonKey(
|
||||
fromJson: JsonTool.stringToProductHourType,
|
||||
toJson: JsonTool.productHourTypeToString,
|
||||
)
|
||||
ProductHourType? hourType;
|
||||
|
||||
/// 优惠类型
|
||||
@JsonKey(
|
||||
fromJson: JsonTool.stringToDiscountsType,
|
||||
toJson: JsonTool.discountsTypeToString,
|
||||
)
|
||||
DiscountsType? type;
|
||||
|
||||
/// 基础金额(分),超过了这个基数`extraPer`就生效
|
||||
int basePrice;
|
||||
|
||||
/// 打折(8折->0.8)
|
||||
double? extraPer;
|
||||
|
||||
DiscountsItem({
|
||||
required this.name,
|
||||
required this.hourType,
|
||||
required this.type,
|
||||
required this.basePrice,
|
||||
required this.extraPer,
|
||||
});
|
||||
|
||||
/// 计算优惠后的价格
|
||||
/// [totalPrice] 总金额(分)
|
||||
/// [return] 优惠的价格(分)
|
||||
int computedDiscountsExtraPrice(int totalPrice) {
|
||||
if (totalPrice <= basePrice) return 0;
|
||||
final rate = extraPer ?? 1.0;
|
||||
if (rate == 1.0) return 0;
|
||||
return (totalPrice * (rate - 1)).round();
|
||||
}
|
||||
|
||||
factory DiscountsItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$DiscountsItemFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$DiscountsItemToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
@Entity(tableName: "user_record")
|
||||
class UserEntity extends Equatable {
|
||||
@@ -38,6 +91,12 @@ class UserEntity extends Equatable {
|
||||
/// 用户所属的商户id(主要用于机器的离线模式)
|
||||
String? canteenId;
|
||||
|
||||
/// 优惠活动
|
||||
List<DiscountsItem>? discountsList;
|
||||
|
||||
/// 优惠活动更新时间
|
||||
DateTime? discountsUpdateTime;
|
||||
|
||||
/// 创建时间
|
||||
DateTime? createTime;
|
||||
|
||||
@@ -59,6 +118,28 @@ class UserEntity extends Equatable {
|
||||
this.updateTime,
|
||||
});
|
||||
|
||||
/// 计算优惠后的价格
|
||||
/// [totalPrice] 总金额(分)
|
||||
/// [return] 优惠的价格(分)
|
||||
int computedDiscountsPrice(int totalPrice) {
|
||||
if (ObjectUtil.isEmpty(discountsList)) {
|
||||
return 0;
|
||||
}
|
||||
var discountsPrice = 0;
|
||||
for (final item in discountsList!) {
|
||||
discountsPrice += item.computedDiscountsExtraPrice(totalPrice);
|
||||
}
|
||||
return discountsPrice;
|
||||
}
|
||||
|
||||
/// 根据`discountsUpdateTime`来计算,最小更新时间30s
|
||||
bool isUpdateDiscounts() {
|
||||
if (ObjectUtil.isEmpty(discountsUpdateTime)) {
|
||||
return true;
|
||||
}
|
||||
return DateTime.now().difference(discountsUpdateTime!).inSeconds > 30;
|
||||
}
|
||||
|
||||
factory UserEntity.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserEntityFromJson(json);
|
||||
|
||||
|
||||
@@ -6,6 +6,24 @@ part of 'user_entity.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
DiscountsItem _$DiscountsItemFromJson(Map<String, dynamic> json) =>
|
||||
DiscountsItem(
|
||||
name: json['name'] as String,
|
||||
hourType: JsonTool.stringToProductHourType(json['hourType'] as String?),
|
||||
type: JsonTool.stringToDiscountsType(json['type'] as String?),
|
||||
basePrice: (json['basePrice'] as num).toInt(),
|
||||
extraPer: (json['extraPer'] as num?)?.toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DiscountsItemToJson(DiscountsItem instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'hourType': JsonTool.productHourTypeToString(instance.hourType),
|
||||
'type': JsonTool.discountsTypeToString(instance.type),
|
||||
'basePrice': instance.basePrice,
|
||||
'extraPer': instance.extraPer,
|
||||
};
|
||||
|
||||
UserEntity _$UserEntityFromJson(Map<String, dynamic> json) => UserEntity(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
userId: json['userId'] as String,
|
||||
@@ -23,7 +41,13 @@ UserEntity _$UserEntityFromJson(Map<String, dynamic> json) => UserEntity(
|
||||
updateTime: json['updateTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updateTime'] as String),
|
||||
);
|
||||
)
|
||||
..discountsList = (json['discountsList'] as List<dynamic>?)
|
||||
?.map((e) => DiscountsItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..discountsUpdateTime = json['discountsUpdateTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['discountsUpdateTime'] as String);
|
||||
|
||||
Map<String, dynamic> _$UserEntityToJson(UserEntity instance) =>
|
||||
<String, dynamic>{
|
||||
@@ -37,6 +61,8 @@ Map<String, dynamic> _$UserEntityToJson(UserEntity instance) =>
|
||||
'walletTypeId': instance.walletTypeId,
|
||||
'walletBalance': instance.walletBalance,
|
||||
'canteenId': instance.canteenId,
|
||||
'discountsList': instance.discountsList,
|
||||
'discountsUpdateTime': instance.discountsUpdateTime?.toIso8601String(),
|
||||
'createTime': instance.createTime?.toIso8601String(),
|
||||
'updateTime': instance.updateTime?.toIso8601String(),
|
||||
};
|
||||
@@ -119,6 +119,18 @@ class SupermarketNatureConverter extends TypeConverter<ProductNature, String> {
|
||||
}
|
||||
}
|
||||
|
||||
class DiscountsTypeConverter extends TypeConverter<DiscountsType, String> {
|
||||
@override
|
||||
DiscountsType decode(String databaseValue) {
|
||||
return DiscountsType.values.byName(databaseValue);
|
||||
}
|
||||
|
||||
@override
|
||||
String encode(DiscountsType value) {
|
||||
return value.name;
|
||||
}
|
||||
}
|
||||
|
||||
class ListIntConverter extends TypeConverter<List<dynamic>?, String> {
|
||||
@override
|
||||
List<dynamic> decode(String databaseValue) {
|
||||
@@ -137,6 +149,28 @@ class ListIntConverter extends TypeConverter<List<dynamic>?, String> {
|
||||
}
|
||||
}
|
||||
|
||||
class ListDiscountsConverter
|
||||
extends TypeConverter<List<DiscountsItem>?, String> {
|
||||
@override
|
||||
List<DiscountsItem> decode(String databaseValue) {
|
||||
if (databaseValue.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
return json
|
||||
.decode(databaseValue)
|
||||
.map((e) => DiscountsItem.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
String encode(List<DiscountsItem>? value) {
|
||||
if (ObjectUtil.isEmptyList(value)) {
|
||||
return '';
|
||||
}
|
||||
return json.encode(value);
|
||||
}
|
||||
}
|
||||
|
||||
class BoolConverter extends TypeConverter<bool, int> {
|
||||
@override
|
||||
bool decode(int databaseValue) {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
class DiscountsTool {
|
||||
/// 更新用户优惠列表
|
||||
static Future<List<DiscountsItem>?> updateUserDiscountsList({
|
||||
required String userId,
|
||||
}) async {
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final params = {
|
||||
"userId": userId,
|
||||
"hardId": sysSetting.serviceId,
|
||||
};
|
||||
final discountsRes = await WalletApi.getDiscountsListByUserId(params);
|
||||
if (ObjectUtil.isEmpty(discountsRes)) return null;
|
||||
final app = Get.find<AppControl>();
|
||||
final userDao = app.dataBase.getUserDao;
|
||||
// 查询用户表
|
||||
final userEntity = await userDao.findByUserId(userId);
|
||||
if (ObjectUtil.isEmpty(userEntity)) return discountsRes;
|
||||
// 能更新优惠(防止同一个用户频繁更新)
|
||||
if (userEntity!.isUpdateDiscounts()) {
|
||||
userEntity.discountsList = discountsRes;
|
||||
userEntity.discountsUpdateTime = DateTime.now();
|
||||
await userDao.edit(userEntity);
|
||||
}
|
||||
// 更新到用户表
|
||||
return discountsRes;
|
||||
}
|
||||
|
||||
/// 计算额外增加的金额
|
||||
/// [totalPrice] 总金额(分)
|
||||
/// [discountsItem] 优惠项
|
||||
/// [return] 额外增加的金额(分)
|
||||
static Future<int> computedExtraPrice({
|
||||
required String userId,
|
||||
required int totalPrice,
|
||||
required String hourType,
|
||||
}) async {
|
||||
var discountsItems = await updateUserDiscountsList(userId: userId);
|
||||
discountsItems = discountsItems
|
||||
?.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;
|
||||
if (extraPer == null || extraPer <= 1.0) continue;
|
||||
extraPrice += item.computedDiscountsExtraPrice(totalPrice);
|
||||
}
|
||||
return extraPrice;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ export './app/app_setting_tool.dart';
|
||||
export './app/app_sys_tool.dart';
|
||||
export './app/app_user_tool.dart';
|
||||
|
||||
export './discounts/discounts_tool.dart';
|
||||
|
||||
export './json/json_tool.dart';
|
||||
|
||||
export './keyboard/keyboard_tool.dart';
|
||||
|
||||
@@ -56,4 +56,22 @@ abstract class JsonTool {
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
static DiscountsType? stringToDiscountsType(String? value) {
|
||||
return DiscountsType.values.fromCode(value);
|
||||
}
|
||||
|
||||
static String? discountsTypeToString(DiscountsType? value) {
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
static ProductHourType? stringToProductHourType(String? value) {
|
||||
return ProductHourType.values.fromCode(value);
|
||||
}
|
||||
|
||||
static String? productHourTypeToString(ProductHourType? value) {
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,9 @@ class Constants {
|
||||
static const pwdEncKey = 'pigxpigxpigxpigx';
|
||||
|
||||
/// 服务 url 线上
|
||||
static const apiUrl = 'https://stgl.pj.gov.cn/api';
|
||||
// static const apiUrl = 'https://stgl.pj.gov.cn/api';
|
||||
|
||||
// static const apiUrl = 'http://192.168.101.104:9999';
|
||||
static const apiUrl = 'https://rj4jv5rwqs.by.takin.cc';
|
||||
|
||||
/// 静态资源 url
|
||||
static const ossUrl = apiUrl;
|
||||
|
||||
@@ -39,5 +39,21 @@ Widget appUserInfo(
|
||||
appPrice(context, balance),
|
||||
].toRow().offstage(offstage: !visibleMoney),
|
||||
].toColumn(crossAxisAlignment: CrossAxisAlignment.start),
|
||||
].toRow(mainAxisAlignment: MainAxisAlignment.center).width(double.infinity);
|
||||
<Widget>[
|
||||
FButton(
|
||||
label: Text(
|
||||
"识别",
|
||||
style: theme.typography.base.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
style: FButtonStyle.outline,
|
||||
onPress: () {},
|
||||
).width(100.w).height(50.w).offstage(offstage: true),
|
||||
].toColumn(),
|
||||
]
|
||||
.toRow(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
)
|
||||
.width(double.infinity);
|
||||
}
|
||||
@@ -268,17 +268,19 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
|
||||
// 计算额外的价格
|
||||
Future<void> _computedAmountMealPrice() async {
|
||||
// final price = await getAmountMealPrice(
|
||||
// price: totalPrice.value,
|
||||
var extraPrice = 0;
|
||||
// final extraPrice = await _getMchRulePrice(
|
||||
// totalPrice.value,
|
||||
// userCanteenId: payUser.value?.canteenId,
|
||||
// );
|
||||
// if (ObjectUtil.isNotEmpty(price)) {
|
||||
// amountMealPrice.value = int.parse(price!.toString());
|
||||
// sendSubScreen();
|
||||
// }
|
||||
final extraPrice = await _getMchRulePrice(
|
||||
totalPrice.value,
|
||||
userCanteenId: payUser.value?.canteenId,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(payUser.value?.userId) &&
|
||||
ObjectUtil.isNotEmpty(hourType.value)) {
|
||||
extraPrice = await DiscountsTool.computedExtraPrice(
|
||||
userId: payUser.value?.userId ?? "",
|
||||
totalPrice: totalPrice.value,
|
||||
hourType: hourType.value.code,
|
||||
);
|
||||
}
|
||||
if (extraPrice != 0) {
|
||||
amountMealPrice.value = extraPrice;
|
||||
sendSubScreen();
|
||||
|
||||
@@ -21,10 +21,10 @@ Future<void> _bindServiceDialog(BuildContext context, SysSetting sys) async {
|
||||
// 正式环境-测试
|
||||
// uniqueCodeC.text = "1896157295523049473";
|
||||
// 正式环境-新县府02-主要测试
|
||||
uniqueCodeC.text = "1887466308336488450";
|
||||
// uniqueCodeC.text = "1887466308336488450";
|
||||
|
||||
/// 测试环境-测试设备-(食堂主要测试)
|
||||
// uniqueCodeC.text = "1877592554489143298";
|
||||
uniqueCodeC.text = "1877592554489143298";
|
||||
// 测试少年宫测试
|
||||
// uniqueCodeC.text = "1927932460185784321";
|
||||
// 测试环境-食堂-浦阳
|
||||
|
||||
Reference in new issue
Block a user