feat:交易记录、日期组建
This commit is contained in:
1 parent
08ad1c2d81
commit
88e73ad950
32 files changed
+672
-279
No files matched your search
@@ -39,6 +39,9 @@ class MainApp extends StatelessWidget {
|
||||
getPages: RoutePages.list,
|
||||
enableLog: true,
|
||||
debugShowCheckedModeBanner: false,
|
||||
locale: const Locale('zh', 'CN'),
|
||||
localizationsDelegates: FLocalizations.localizationsDelegates,
|
||||
supportedLocales: FLocalizations.supportedLocales,
|
||||
builder: EasyLoading.init(
|
||||
builder: (context, child) => FTheme(
|
||||
data: themeData,
|
||||
|
||||
@@ -72,6 +72,9 @@ class ServiceProduct {
|
||||
/// 用餐类型,早餐、中餐、晚餐
|
||||
String? categoryType;
|
||||
|
||||
/// 菜品上架日期
|
||||
DateTime? saleDate;
|
||||
|
||||
ServiceProduct({
|
||||
this.id,
|
||||
this.spuId,
|
||||
@@ -81,6 +84,7 @@ class ServiceProduct {
|
||||
this.hourType,
|
||||
this.sort,
|
||||
this.categoryType,
|
||||
this.saleDate,
|
||||
});
|
||||
|
||||
factory ServiceProduct.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -38,6 +38,9 @@ ServiceProduct _$ServiceProductFromJson(Map<String, dynamic> json) =>
|
||||
hourType: JsonTool.anyToString(json['hourType']),
|
||||
sort: (json['sort'] as num?)?.toInt(),
|
||||
categoryType: json['categoryType'] as String?,
|
||||
saleDate: json['saleDate'] == null
|
||||
? null
|
||||
: DateTime.parse(json['saleDate'] as String),
|
||||
)..price = (json['price'] as num?)?.toInt();
|
||||
|
||||
Map<String, dynamic> _$ServiceProductToJson(ServiceProduct instance) =>
|
||||
@@ -51,4 +54,5 @@ Map<String, dynamic> _$ServiceProductToJson(ServiceProduct instance) =>
|
||||
'price': instance.price,
|
||||
'sort': instance.sort,
|
||||
'categoryType': instance.categoryType,
|
||||
'saleDate': instance.saleDate?.toIso8601String(),
|
||||
};
|
||||
@@ -54,7 +54,7 @@ enum OrderPayType implements BaseEnum {
|
||||
/// 订单状态
|
||||
enum OrderStatus implements BaseEnum {
|
||||
// 查询使用
|
||||
total("-1", "未付款"),
|
||||
total("-1", "全部"),
|
||||
|
||||
nonePay("1", "未付款"),
|
||||
pay("5", "已付款"),
|
||||
|
||||
@@ -88,6 +88,18 @@ class SysSetting extends Equatable {
|
||||
/// 长链接重连
|
||||
DateTime? mqSyncTime;
|
||||
|
||||
/// 商品时间段类型
|
||||
ProductHourType? hourType;
|
||||
|
||||
// 全局字体大小
|
||||
SettingGlobalFontSize? globalFontSize;
|
||||
|
||||
// 使用支付方式
|
||||
List<OrderPayDisplayType>? usePayDisplayType;
|
||||
|
||||
// 默认支付方式
|
||||
OrderPayDisplayType? defaultPayDisplayType;
|
||||
|
||||
SysSetting({
|
||||
required this.sysType,
|
||||
this.androidId,
|
||||
@@ -133,6 +145,10 @@ class SysSetting extends Equatable {
|
||||
supermarketProductSyncTime?.millisecondsSinceEpoch,
|
||||
offlineOrderSyncTime?.millisecondsSinceEpoch,
|
||||
mqSyncTime?.millisecondsSinceEpoch,
|
||||
hourType,
|
||||
globalFontSize,
|
||||
usePayDisplayType,
|
||||
defaultPayDisplayType,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -164,12 +180,6 @@ class UserSetting extends Equatable {
|
||||
|
||||
/// end 服务端信息 end
|
||||
|
||||
/// 商品时间段类型
|
||||
ProductHourType? hourType;
|
||||
|
||||
// 全局字体大小
|
||||
SettingGlobalFontSize? globalFontSize;
|
||||
|
||||
UserSetting({
|
||||
this.username,
|
||||
this.password,
|
||||
@@ -189,7 +199,6 @@ class UserSetting extends Equatable {
|
||||
accessToken,
|
||||
refreshToken,
|
||||
expiresTime,
|
||||
hourType,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,16 @@ SysSetting _$SysSettingFromJson(Map<String, dynamic> json) => SysSetting(
|
||||
: DateTime.parse(json['offlineOrderSyncTime'] as String)
|
||||
..mqSyncTime = json['mqSyncTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['mqSyncTime'] as String);
|
||||
: DateTime.parse(json['mqSyncTime'] as String)
|
||||
..hourType =
|
||||
$enumDecodeNullable(_$ProductHourTypeEnumMap, json['hourType'])
|
||||
..globalFontSize = $enumDecodeNullable(
|
||||
_$SettingGlobalFontSizeEnumMap, json['globalFontSize'])
|
||||
..usePayDisplayType = (json['usePayDisplayType'] as List<dynamic>?)
|
||||
?.map((e) => $enumDecode(_$OrderPayDisplayTypeEnumMap, e))
|
||||
.toList()
|
||||
..defaultPayDisplayType = $enumDecodeNullable(
|
||||
_$OrderPayDisplayTypeEnumMap, json['defaultPayDisplayType']);
|
||||
|
||||
Map<String, dynamic> _$SysSettingToJson(SysSetting instance) =>
|
||||
<String, dynamic>{
|
||||
@@ -84,6 +93,13 @@ Map<String, dynamic> _$SysSettingToJson(SysSetting instance) =>
|
||||
instance.supermarketProductSyncTime?.toIso8601String(),
|
||||
'offlineOrderSyncTime': instance.offlineOrderSyncTime?.toIso8601String(),
|
||||
'mqSyncTime': instance.mqSyncTime?.toIso8601String(),
|
||||
'hourType': _$ProductHourTypeEnumMap[instance.hourType],
|
||||
'globalFontSize': _$SettingGlobalFontSizeEnumMap[instance.globalFontSize],
|
||||
'usePayDisplayType': instance.usePayDisplayType
|
||||
?.map((e) => _$OrderPayDisplayTypeEnumMap[e]!)
|
||||
.toList(),
|
||||
'defaultPayDisplayType':
|
||||
_$OrderPayDisplayTypeEnumMap[instance.defaultPayDisplayType],
|
||||
};
|
||||
|
||||
const _$SysTypeEnumMap = {
|
||||
@@ -91,33 +107,6 @@ const _$SysTypeEnumMap = {
|
||||
SysType.canteen: 'canteen',
|
||||
};
|
||||
|
||||
UserSetting _$UserSettingFromJson(Map<String, dynamic> json) => UserSetting(
|
||||
username: json['username'] as String?,
|
||||
password: json['password'] as String?,
|
||||
)
|
||||
..sysType = $enumDecodeNullable(_$SysTypeEnumMap, json['sysType'])
|
||||
..userId = (json['userId'] as num?)?.toInt()
|
||||
..accessToken = json['accessToken'] as String?
|
||||
..refreshToken = json['refreshToken'] as String?
|
||||
..expiresTime = (json['expiresTime'] as num?)?.toInt()
|
||||
..hourType =
|
||||
$enumDecodeNullable(_$ProductHourTypeEnumMap, json['hourType'])
|
||||
..globalFontSize = $enumDecodeNullable(
|
||||
_$SettingGlobalFontSizeEnumMap, json['globalFontSize']);
|
||||
|
||||
Map<String, dynamic> _$UserSettingToJson(UserSetting instance) =>
|
||||
<String, dynamic>{
|
||||
'username': instance.username,
|
||||
'password': instance.password,
|
||||
'sysType': _$SysTypeEnumMap[instance.sysType],
|
||||
'userId': instance.userId,
|
||||
'accessToken': instance.accessToken,
|
||||
'refreshToken': instance.refreshToken,
|
||||
'expiresTime': instance.expiresTime,
|
||||
'hourType': _$ProductHourTypeEnumMap[instance.hourType],
|
||||
'globalFontSize': _$SettingGlobalFontSizeEnumMap[instance.globalFontSize],
|
||||
};
|
||||
|
||||
const _$ProductHourTypeEnumMap = {
|
||||
ProductHourType.all: 'all',
|
||||
ProductHourType.morning: 'morning',
|
||||
@@ -132,6 +121,34 @@ const _$SettingGlobalFontSizeEnumMap = {
|
||||
SettingGlobalFontSize.xl4: 'xl4',
|
||||
};
|
||||
|
||||
const _$OrderPayDisplayTypeEnumMap = {
|
||||
OrderPayDisplayType.qrCode: 'qrCode',
|
||||
OrderPayDisplayType.walletCard: 'walletCard',
|
||||
OrderPayDisplayType.face: 'face',
|
||||
OrderPayDisplayType.cash: 'cash',
|
||||
};
|
||||
|
||||
UserSetting _$UserSettingFromJson(Map<String, dynamic> json) => UserSetting(
|
||||
username: json['username'] as String?,
|
||||
password: json['password'] as String?,
|
||||
)
|
||||
..sysType = $enumDecodeNullable(_$SysTypeEnumMap, json['sysType'])
|
||||
..userId = (json['userId'] as num?)?.toInt()
|
||||
..accessToken = json['accessToken'] as String?
|
||||
..refreshToken = json['refreshToken'] as String?
|
||||
..expiresTime = (json['expiresTime'] as num?)?.toInt();
|
||||
|
||||
Map<String, dynamic> _$UserSettingToJson(UserSetting instance) =>
|
||||
<String, dynamic>{
|
||||
'username': instance.username,
|
||||
'password': instance.password,
|
||||
'sysType': _$SysTypeEnumMap[instance.sysType],
|
||||
'userId': instance.userId,
|
||||
'accessToken': instance.accessToken,
|
||||
'refreshToken': instance.refreshToken,
|
||||
'expiresTime': instance.expiresTime,
|
||||
};
|
||||
|
||||
CanteenExtraPriceSetting _$CanteenExtraPriceSettingFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
CanteenExtraPriceSetting(
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class OrderDao {
|
||||
(:status == "-1" OR status = :status) AND
|
||||
(:sysType = '-1' OR sysType = :sysType) AND
|
||||
(:hourType = '-1' OR hourType = :hourType) AND
|
||||
createTime >= :startCreateOrderTime AND createTime <= :endCreateOrderTime
|
||||
strftime('%Y-%m-%d', createTime) >= strftime('%Y-%m-%d', :startCreateOrderTime) AND strftime('%Y-%m-%d', createTime) <= strftime('%Y-%m-%d', :endCreateOrderTime)
|
||||
ORDER BY createTime DESC
|
||||
LIMIT :pageSize OFFSET :offset
|
||||
''')
|
||||
@@ -53,7 +53,7 @@ abstract class OrderDao {
|
||||
(:status == "-1" OR status = :status) AND
|
||||
(:sysType = '-1' OR sysType = :sysType) AND
|
||||
(:hourType = '-1' OR hourType = :hourType) AND
|
||||
createTime >= :startCreateOrderTime AND createTime <= :endCreateOrderTime
|
||||
strftime('%Y-%m-%d', createTime) >= strftime('%Y-%m-%d', :startCreateOrderTime) AND strftime('%Y-%m-%d', createTime) <= strftime('%Y-%m-%d', :endCreateOrderTime)
|
||||
''')
|
||||
Future<int?> count(
|
||||
String status,
|
||||
|
||||
@@ -19,6 +19,7 @@ abstract class ProductDao {
|
||||
final placeholders = List.generate(codes.length, (index) => '?').join(', ');
|
||||
final sql = '''
|
||||
UPDATE product SET delFlag = 1 WHERE serviceUniqueCode IN ($placeholders)
|
||||
AND (sysType = 'canteen' OR strftime('%Y-%m-%d', saleDate) = strftime('%Y-%m-%d', 'now', 'localtime'))
|
||||
''';
|
||||
return await database.rawUpdate(sql, [...codes]);
|
||||
}
|
||||
@@ -38,7 +39,9 @@ abstract class ProductDao {
|
||||
@Query("""
|
||||
UPDATE product SET isDefault = :isDefault
|
||||
WHERE
|
||||
delFlag = 0 AND serviceUniqueCode = :uniqueCode AND hourType = :hourType
|
||||
delFlag = 0
|
||||
AND serviceUniqueCode = :uniqueCode AND hourType = :hourType
|
||||
AND (sysType = 'canteen' OR strftime('%Y-%m-%d', saleDate) = strftime('%Y-%m-%d', 'now', 'localtime'))
|
||||
""")
|
||||
Future<void> edit(bool isDefault, String uniqueCode, String hourType);
|
||||
|
||||
@@ -51,6 +54,7 @@ abstract class ProductDao {
|
||||
delFlag = 0
|
||||
AND (:sysType = '-1' OR sysType = :sysType)
|
||||
AND (:hourType = '-1' OR INSTR(',' || hourType || ',', ',' || :hourType || ',') > 0)
|
||||
AND (:sysType = 'canteen' OR strftime('%Y-%m-%d', saleDate) = strftime('%Y-%m-%d', 'now', 'localtime'))
|
||||
""")
|
||||
Future<int?> getCount(
|
||||
String sysType,
|
||||
@@ -88,11 +92,12 @@ abstract class ProductDao {
|
||||
product.delFlag = 0 AND
|
||||
(:classifyServiceUniqueCode = '-1' OR product.classifyServiceUniqueCode = :classifyServiceUniqueCode) AND
|
||||
(:hourType = '-1' OR INSTR(',' || product.hourType || ',', ',' || :hourType || ',') > 0) AND
|
||||
(:sysType = '-1' OR product.sysType = :sysType)
|
||||
(:sysType = '-1' OR product.sysType = :sysType) AND
|
||||
(:sysType = 'canteen' OR strftime('%Y-%m-%d', product.saleDate) = strftime('%Y-%m-%d', 'now', 'localtime'))
|
||||
ORDER BY classify.sort, classify.id, product.price
|
||||
LIMIT :pageSize OFFSET :offset
|
||||
''')
|
||||
Future<List<ProductEntity>> getCurrentDayAllPage(
|
||||
Future<List<ProductEntity>> getAllPage(
|
||||
String classifyServiceUniqueCode,
|
||||
String hourType,
|
||||
String sysType,
|
||||
@@ -103,10 +108,11 @@ abstract class ProductDao {
|
||||
@Query('''
|
||||
SELECT * FROM product
|
||||
WHERE
|
||||
product.delFlag = 0
|
||||
delFlag = 0
|
||||
AND isDefault = 1
|
||||
AND (:sysType = '-1' OR sysType = :sysType)
|
||||
AND (:hourType = '-1' OR hourType = :hourType)
|
||||
AND (:sysType = 'canteen' OR strftime('%Y-%m-%d', saleDate) = strftime('%Y-%m-%d', 'now', 'localtime'))
|
||||
''')
|
||||
Future<List<ProductEntity>> getDefault(String sysType, String hourType);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ class _$AppDatabase extends AppDatabase {
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `order_record` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `uniqueCode` TEXT NOT NULL, `serviceUniqueCode` TEXT NOT NULL, `sysType` TEXT NOT NULL, `userCode` TEXT NOT NULL, `username` TEXT, `hourType` TEXT, `price` INTEGER NOT NULL, `extraPrice` INTEGER NOT NULL, `payPrice` INTEGER NOT NULL, `walletId` TEXT, `orderSourceTypeId` TEXT, `type` TEXT NOT NULL, `status` TEXT NOT NULL, `payType` TEXT NOT NULL, `productDesc` TEXT, `count` INTEGER NOT NULL, `weight` REAL NOT NULL, `payTime` TEXT, `createTime` TEXT NOT NULL)');
|
||||
await database.execute(
|
||||
'CREATE TABLE IF NOT EXISTS `product` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `serviceUniqueCode` TEXT NOT NULL, `sysType` TEXT NOT NULL, `classifyServiceUniqueCode` TEXT NOT NULL, `hourType` INTEGER, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `image` TEXT, `isDefault` INTEGER NOT NULL, `status` INTEGER NOT NULL, `sort` INTEGER NOT NULL, `createTime` TEXT NOT NULL, `updateTime` TEXT NOT NULL, `delFlag` INTEGER NOT NULL)');
|
||||
'CREATE TABLE IF NOT EXISTS `product` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `serviceUniqueCode` TEXT NOT NULL, `sysType` TEXT NOT NULL, `classifyServiceUniqueCode` TEXT NOT NULL, `hourType` INTEGER, `saleDate` TEXT, `name` TEXT NOT NULL, `price` INTEGER NOT NULL, `image` TEXT, `isDefault` INTEGER NOT NULL, `status` INTEGER NOT NULL, `sort` INTEGER NOT NULL, `createTime` TEXT NOT NULL, `updateTime` TEXT NOT NULL, `delFlag` INTEGER 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)');
|
||||
await database.execute(
|
||||
@@ -287,7 +287,7 @@ class _$OrderDao extends OrderDao {
|
||||
String hourType,
|
||||
) async {
|
||||
return _queryAdapter.queryList(
|
||||
'SELECT * FROM order_record WHERE (?1 == \"-1\" OR status = ?1) AND (?6 = \'-1\' OR sysType = ?6) AND (?7 = \'-1\' OR hourType = ?7) AND createTime >= ?2 AND createTime <= ?3 ORDER BY createTime DESC LIMIT ?4 OFFSET ?5',
|
||||
'SELECT * FROM order_record WHERE (?1 == \"-1\" OR status = ?1) AND (?6 = \'-1\' OR sysType = ?6) AND (?7 = \'-1\' OR hourType = ?7) AND strftime(\'%Y-%m-%d\', createTime) >= strftime(\'%Y-%m-%d\', ?2) AND strftime(\'%Y-%m-%d\', createTime) <= strftime(\'%Y-%m-%d\', ?3) ORDER BY createTime DESC LIMIT ?4 OFFSET ?5',
|
||||
mapper: (Map<String, Object?> row) => OrderEntity(
|
||||
id: row['id'] as int?,
|
||||
uniqueCode: row['uniqueCode'] as String,
|
||||
@@ -329,7 +329,7 @@ class _$OrderDao extends OrderDao {
|
||||
String hourType,
|
||||
) async {
|
||||
return _queryAdapter.query(
|
||||
'SELECT COUNT(0) FROM order_record WHERE (?1 == \"-1\" OR status = ?1) AND (?4 = \'-1\' OR sysType = ?4) AND (?5 = \'-1\' OR hourType = ?5) AND createTime >= ?2 AND createTime <= ?3',
|
||||
'SELECT COUNT(0) FROM order_record WHERE (?1 == \"-1\" OR status = ?1) AND (?4 = \'-1\' OR sysType = ?4) AND (?5 = \'-1\' OR hourType = ?5) AND strftime(\'%Y-%m-%d\', createTime) >= strftime(\'%Y-%m-%d\', ?2) AND strftime(\'%Y-%m-%d\', createTime) <= strftime(\'%Y-%m-%d\', ?3)',
|
||||
mapper: (Map<String, Object?> row) => row.values.first as int,
|
||||
arguments: [
|
||||
status,
|
||||
@@ -452,6 +452,7 @@ class _$ProductDao extends ProductDao {
|
||||
'sysType': _sysTypeConverter.encode(item.sysType),
|
||||
'classifyServiceUniqueCode': item.classifyServiceUniqueCode,
|
||||
'hourType': item.hourType?.index,
|
||||
'saleDate': _dateTimeEmptyConverter.encode(item.saleDate),
|
||||
'name': item.name,
|
||||
'price': item.price,
|
||||
'image': item.image,
|
||||
@@ -472,6 +473,7 @@ class _$ProductDao extends ProductDao {
|
||||
'sysType': _sysTypeConverter.encode(item.sysType),
|
||||
'classifyServiceUniqueCode': item.classifyServiceUniqueCode,
|
||||
'hourType': item.hourType?.index,
|
||||
'saleDate': _dateTimeEmptyConverter.encode(item.saleDate),
|
||||
'name': item.name,
|
||||
'price': item.price,
|
||||
'image': item.image,
|
||||
@@ -492,6 +494,7 @@ class _$ProductDao extends ProductDao {
|
||||
'sysType': _sysTypeConverter.encode(item.sysType),
|
||||
'classifyServiceUniqueCode': item.classifyServiceUniqueCode,
|
||||
'hourType': item.hourType?.index,
|
||||
'saleDate': _dateTimeEmptyConverter.encode(item.saleDate),
|
||||
'name': item.name,
|
||||
'price': item.price,
|
||||
'image': item.image,
|
||||
@@ -529,7 +532,7 @@ class _$ProductDao extends ProductDao {
|
||||
String hourType,
|
||||
) async {
|
||||
await _queryAdapter.queryNoReturn(
|
||||
'UPDATE product SET isDefault = ?1 WHERE delFlag = 0 AND serviceUniqueCode = ?2 AND hourType = ?3',
|
||||
'UPDATE product SET isDefault = ?1 WHERE delFlag = 0 AND serviceUniqueCode = ?2 AND hourType = ?3 AND (sysType = \'canteen\' OR strftime(\'%Y-%m-%d\', saleDate) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\'))',
|
||||
arguments: [_boolConverter.encode(isDefault), uniqueCode, hourType]);
|
||||
}
|
||||
|
||||
@@ -539,7 +542,7 @@ class _$ProductDao extends ProductDao {
|
||||
String hourType,
|
||||
) async {
|
||||
return _queryAdapter.query(
|
||||
'SELECT DISTINCT COUNT(0) FROM product WHERE delFlag = 0 AND (?1 = \'-1\' OR sysType = ?1) AND (?2 = \'-1\' OR INSTR(\',\' || hourType || \',\', \',\' || ?2 || \',\') > 0)',
|
||||
'SELECT DISTINCT COUNT(0) FROM product WHERE delFlag = 0 AND (?1 = \'-1\' OR sysType = ?1) AND (?2 = \'-1\' OR INSTR(\',\' || hourType || \',\', \',\' || ?2 || \',\') > 0) AND (?1 = \'canteen\' OR strftime(\'%Y-%m-%d\', saleDate) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\'))',
|
||||
mapper: (Map<String, Object?> row) => row.values.first as int,
|
||||
arguments: [sysType, hourType]);
|
||||
}
|
||||
@@ -557,6 +560,7 @@ class _$ProductDao extends ProductDao {
|
||||
hourType: row['hourType'] == null
|
||||
? null
|
||||
: ProductHourType.values[row['hourType'] as int],
|
||||
saleDate: _dateTimeEmptyConverter.decode(row['saleDate'] as String),
|
||||
name: row['name'] as String,
|
||||
price: row['price'] as int,
|
||||
image: row['image'] as String?,
|
||||
@@ -577,12 +581,12 @@ class _$ProductDao extends ProductDao {
|
||||
) async {
|
||||
return _queryAdapter.queryList(
|
||||
'SELECT product.* FROM product LEFT JOIN classify ON product.classifyServiceUniqueCode = classify.serviceUniqueCode WHERE product.delFlag = 0 AND (?1 = \'-1\' OR product.classifyServiceUniqueCode = ?1) AND (?2 = \'-1\' OR INSTR(\',\' || hourType || \',\', \',\' || ?2 || \',\') > 0) AND (?3 = \'-1\' OR product.sysType = ?3) ORDER BY classify.sort, product.price',
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], saleDate: _dateTimeEmptyConverter.decode(row['saleDate'] as String), name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
arguments: [classifyServiceUniqueCode, hourType, sysType]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ProductEntity>> getCurrentDayAllPage(
|
||||
Future<List<ProductEntity>> getAllPage(
|
||||
String classifyServiceUniqueCode,
|
||||
String hourType,
|
||||
String sysType,
|
||||
@@ -590,8 +594,8 @@ class _$ProductDao extends ProductDao {
|
||||
int offset,
|
||||
) async {
|
||||
return _queryAdapter.queryList(
|
||||
'SELECT product.* FROM product LEFT JOIN classify ON product.classifyServiceUniqueCode = classify.serviceUniqueCode WHERE product.delFlag = 0 AND (?1 = \'-1\' OR product.classifyServiceUniqueCode = ?1) AND (?2 = \'-1\' OR INSTR(\',\' || product.hourType || \',\', \',\' || ?2 || \',\') > 0) AND (?3 = \'-1\' OR product.sysType = ?3) ORDER BY classify.sort, classify.id, product.price LIMIT ?4 OFFSET ?5',
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
'SELECT product.* FROM product LEFT JOIN classify ON product.classifyServiceUniqueCode = classify.serviceUniqueCode WHERE product.delFlag = 0 AND (?1 = \'-1\' OR product.classifyServiceUniqueCode = ?1) AND (?2 = \'-1\' OR INSTR(\',\' || product.hourType || \',\', \',\' || ?2 || \',\') > 0) AND (?3 = \'-1\' OR product.sysType = ?3) AND (?3 = \'canteen\' OR strftime(\'%Y-%m-%d\', product.saleDate) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\')) ORDER BY classify.sort, classify.id, product.price LIMIT ?4 OFFSET ?5',
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], saleDate: _dateTimeEmptyConverter.decode(row['saleDate'] as String), name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
arguments: [
|
||||
classifyServiceUniqueCode,
|
||||
hourType,
|
||||
@@ -607,8 +611,8 @@ class _$ProductDao extends ProductDao {
|
||||
String hourType,
|
||||
) async {
|
||||
return _queryAdapter.queryList(
|
||||
'SELECT * FROM product WHERE product.delFlag = 0 AND isDefault = 1 AND (?1 = \'-1\' OR sysType = ?1) AND (?2 = \'-1\' OR hourType = ?2)',
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
'SELECT * FROM product WHERE delFlag = 0 AND isDefault = 1 AND (?1 = \'-1\' OR sysType = ?1) AND (?2 = \'-1\' OR hourType = ?2) AND (?1 = \'canteen\' OR strftime(\'%Y-%m-%d\', saleDate) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\'))',
|
||||
mapper: (Map<String, Object?> row) => ProductEntity(id: row['id'] as int?, serviceUniqueCode: row['serviceUniqueCode'] as String, sysType: _sysTypeConverter.decode(row['sysType'] as String), classifyServiceUniqueCode: row['classifyServiceUniqueCode'] as String, hourType: row['hourType'] == null ? null : ProductHourType.values[row['hourType'] as int], saleDate: _dateTimeEmptyConverter.decode(row['saleDate'] as String), name: row['name'] as String, price: row['price'] as int, image: row['image'] as String?, isDefault: _boolConverter.decode(row['isDefault'] as int), status: row['status'] as int, sort: row['sort'] as int, createTime: _dateTimeConverter.decode(row['createTime'] as String), updateTime: _dateTimeConverter.decode(row['updateTime'] as String), delFlag: _boolConverter.decode(row['delFlag'] as int)),
|
||||
arguments: [sysType, hourType]);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ class ProductEntity extends Equatable {
|
||||
/// 菜品时间类型
|
||||
ProductHourType? hourType;
|
||||
|
||||
/// 菜品上架日期
|
||||
DateTime? saleDate;
|
||||
|
||||
/// 商品名
|
||||
String name;
|
||||
|
||||
@@ -57,7 +60,8 @@ class ProductEntity extends Equatable {
|
||||
required this.serviceUniqueCode,
|
||||
required this.sysType,
|
||||
required this.classifyServiceUniqueCode,
|
||||
required this.hourType,
|
||||
this.hourType,
|
||||
this.saleDate,
|
||||
required this.name,
|
||||
required this.price,
|
||||
this.image,
|
||||
|
||||
@@ -13,6 +13,9 @@ ProductEntity _$ProductEntityFromJson(Map<String, dynamic> json) =>
|
||||
sysType: $enumDecode(_$SysTypeEnumMap, json['sysType']),
|
||||
classifyServiceUniqueCode: json['classifyServiceUniqueCode'] as String,
|
||||
hourType: $enumDecodeNullable(_$ProductHourTypeEnumMap, json['hourType']),
|
||||
saleDate: json['saleDate'] == null
|
||||
? null
|
||||
: DateTime.parse(json['saleDate'] as String),
|
||||
name: json['name'] as String,
|
||||
price: (json['price'] as num).toInt(),
|
||||
image: json['image'] as String?,
|
||||
@@ -31,6 +34,7 @@ Map<String, dynamic> _$ProductEntityToJson(ProductEntity instance) =>
|
||||
'sysType': _$SysTypeEnumMap[instance.sysType]!,
|
||||
'classifyServiceUniqueCode': instance.classifyServiceUniqueCode,
|
||||
'hourType': _$ProductHourTypeEnumMap[instance.hourType],
|
||||
'saleDate': instance.saleDate?.toIso8601String(),
|
||||
'name': instance.name,
|
||||
'price': instance.price,
|
||||
'image': instance.image,
|
||||
|
||||
@@ -4,14 +4,15 @@ import 'package:common_utils/common_utils.dart';
|
||||
import 'package:external_path/external_path.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
abstract class AppFileTool {
|
||||
static const _tag = "app文件工具";
|
||||
static const _baseDir = "pj";
|
||||
static const _baseBackupDir = "backup";
|
||||
static const _backupDatabaseDir = ".database";
|
||||
static const _backupDatabaseDir = "database";
|
||||
static const _backupLoggerDir = "logger";
|
||||
static const _backupFaceDir = ".face";
|
||||
static const _backupFaceDir = "face";
|
||||
|
||||
/// 检查并创建目录
|
||||
static Future<String> _checkAndcreateDir(String dir) async {
|
||||
@@ -53,14 +54,14 @@ abstract class AppFileTool {
|
||||
|
||||
/// 创建数据库文件备份地址
|
||||
static Future<String?> getDatabaseBackupPath() async {
|
||||
String backupDir = await getExternalPath();
|
||||
String backupDir = await getExternalPath(backupExternalPath: false);
|
||||
String dir = "$backupDir/$_baseBackupDir/$_backupDatabaseDir";
|
||||
DateTime now = DateTime.now();
|
||||
int year = now.year;
|
||||
int month = now.month;
|
||||
int day = now.day;
|
||||
dir = "$dir/$year-$month";
|
||||
dir = await _checkAndcreateDir(backupDir);
|
||||
dir = await _checkAndcreateDir(dir);
|
||||
dir = "$dir/$day.db";
|
||||
return dir;
|
||||
}
|
||||
@@ -104,13 +105,18 @@ abstract class AppFileTool {
|
||||
logger.e("|$_tag|备份sql文件失败,无效的sourcePath路径path:|$sourcePath|");
|
||||
return false;
|
||||
}
|
||||
final databaseFilePath = "$sourcePath${Constants.databaseName}";
|
||||
if (await File(databaseFilePath).exists()) {
|
||||
logger.w("|$_tag|备份sql文件失败,无效的sourcePath路径path|$databaseFilePath|");
|
||||
return false;
|
||||
}
|
||||
String? backupPath = await getDatabaseBackupPath();
|
||||
if (ObjectUtil.isEmpty(backupPath)) {
|
||||
logger.e("|$_tag|备份sql文件失败,无效的backupPath路径path:|$backupPath|");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await File("$sourcePath/${Constants.databaseName}").copy(backupPath!);
|
||||
await File(databaseFilePath).copy(backupPath!);
|
||||
return true;
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|备份sql文件失败,意外的错误error|$e|stack|$stack|");
|
||||
@@ -118,5 +124,45 @@ abstract class AppFileTool {
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有数据库将最新的数据库移动为使用的数据库
|
||||
static Future<void> useLastBackDatabase() async {
|
||||
final databasePath = getDatabasesPath();
|
||||
final databaseFilePath = "$databasePath${Constants.databaseName}";
|
||||
if (await File(databaseFilePath).exists()) {
|
||||
logger.w("|$_tag|替换数据库错误,数据库文件已存在path|$databaseFilePath|");
|
||||
return;
|
||||
}
|
||||
final path = await getDatabaseBackupPath();
|
||||
if (ObjectUtil.isEmpty(path)) {
|
||||
logger.w("|$_tag|替换数据库错误,无效的数据库备份path|$path|");
|
||||
return;
|
||||
}
|
||||
final dir = Directory(path!).parent;
|
||||
if (!await dir.exists()) {
|
||||
logger.w("|$_tag|替换数据库错误,无效的数据库备份目录path|$dir|");
|
||||
return;
|
||||
}
|
||||
final files = dir.listSync();
|
||||
files.sort(
|
||||
(a, b) => b.statSync().modified.compareTo(a.statSync().modified),
|
||||
);
|
||||
if (files.isEmpty) {
|
||||
logger.w("|$_tag|替换数据库错误,数据库备份目录为空path|$dir|");
|
||||
return;
|
||||
}
|
||||
final lastFile = files.first;
|
||||
try {
|
||||
if (lastFile is File) {
|
||||
final sourcePath = lastFile.path;
|
||||
await File(sourcePath).copy(databaseFilePath);
|
||||
logger.i(
|
||||
"|$_tag|替换数据库成功,sourcePath|$sourcePath|targetPath|$databaseFilePath|",
|
||||
);
|
||||
}
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|替换数据库错误,意外的错误error|$e|stack|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
// 备份日志
|
||||
}
|
||||
@@ -31,8 +31,6 @@ class AppControl extends GetxController {
|
||||
// 是否有网络
|
||||
RxBool isNetwork = RxBool(false);
|
||||
|
||||
Rx<ProductHourType> hourType = Rx(ProductHourType.morning);
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
|
||||
@@ -16,9 +16,9 @@ class AppThemeControl extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
final userInfo = await AppSettingTool.getUserSetting();
|
||||
if (userInfo.globalFontSize != null) {
|
||||
sizeScalar.value = userInfo.globalFontSize!.fontSize;
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
if (appSetting.globalFontSize != null) {
|
||||
sizeScalar.value = appSetting.globalFontSize!.fontSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ abstract class SyncProductTool {
|
||||
DateTime.now(),
|
||||
format: DateFormats.y_mo_d,
|
||||
);
|
||||
final dayStr = DateUtil.getDateTime(day);
|
||||
final pa = {
|
||||
"day": day,
|
||||
"hourType": null,
|
||||
@@ -153,6 +154,9 @@ abstract class SyncProductTool {
|
||||
"merchantId": sysSetting.serviceMerchantId,
|
||||
};
|
||||
apiList = await ProductApi.canteenProduct(pa);
|
||||
if (!ObjectUtil.isEmptyList(apiList)) {
|
||||
apiList?.forEach((v) => v.saleDate = dayStr);
|
||||
}
|
||||
} else if (sysType == SysType.supermarket) {
|
||||
apiList = await ProductApi.supermarketProduct(null);
|
||||
}
|
||||
@@ -246,6 +250,7 @@ abstract class SyncProductTool {
|
||||
createTime: DateTime.now(),
|
||||
updateTime: DateTime.now(),
|
||||
hourType: ProductHourType.values.fromCode(v.hourType),
|
||||
saleDate: v.saleDate,
|
||||
isDefault: false,
|
||||
delFlag: false,
|
||||
);
|
||||
|
||||
@@ -1,15 +1,155 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
|
||||
|
||||
Widget appDatePicer(
|
||||
BuildContext context,
|
||||
) {
|
||||
return FCalendar(
|
||||
controller: FCalendarController.range(
|
||||
initialSelection: (DateTime(2024, 7, 17), DateTime(2024, 7, 20)),
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
Widget appDatePicker(
|
||||
BuildContext context, {
|
||||
required Function(List<DateTime>?) onChnage,
|
||||
required List<DateTime>? datetimeRange,
|
||||
}) {
|
||||
final theme = FTheme.of(context);
|
||||
String detail = "请选择";
|
||||
if (!ObjectUtil.isEmpty(datetimeRange)) {
|
||||
final sartStr = DateUtil.formatDate(
|
||||
datetimeRange![0],
|
||||
format: DateFormats.y_mo_d,
|
||||
);
|
||||
final endStr = DateUtil.formatDate(
|
||||
datetimeRange[1],
|
||||
format: DateFormats.y_mo_d,
|
||||
);
|
||||
detail = "$sartStr-$endStr";
|
||||
}
|
||||
return FTile(
|
||||
prefixIcon: FIcon(
|
||||
FAssets.icons.calendar,
|
||||
size: theme.typography.xl.fontSize,
|
||||
),
|
||||
suffixIcon: FIcon(
|
||||
FAssets.icons.chevronsUpDown,
|
||||
size: theme.typography.sm.fontSize,
|
||||
),
|
||||
title: const SizedBox.shrink(),
|
||||
details: Text(
|
||||
detail,
|
||||
style: theme.typography.base,
|
||||
),
|
||||
onPress: () async {
|
||||
final result = await appShowDatePicker(
|
||||
context,
|
||||
datetimeRange: datetimeRange,
|
||||
);
|
||||
onChnage(result);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<DateTime>?> appShowDatePicker(
|
||||
BuildContext context, {
|
||||
List<DateTime>? datetimeRange,
|
||||
}) async {
|
||||
final theme = FTheme.of(context);
|
||||
final width = context.width;
|
||||
final height = context.height;
|
||||
// 默认时间为当天
|
||||
DateTime startTIme = DateTime.now();
|
||||
DateTime endTime = DateTime.now().add(const Duration(days: 1));
|
||||
if (!ObjectUtil.isEmptyList(datetimeRange)) {
|
||||
startTIme = datetimeRange![0];
|
||||
endTime = datetimeRange[1];
|
||||
}
|
||||
List<DateTime> slectDateTime = [];
|
||||
return await showAdaptiveDialog<List<DateTime>?>(
|
||||
context: context,
|
||||
builder: (context) => FDialog(
|
||||
style: theme.dialogStyle.copyWith(
|
||||
insetPadding: EdgeInsets.zero,
|
||||
maxWidth: width * 0.6,
|
||||
minWidth: width * 0.6,
|
||||
horizontalStyle: theme.dialogStyle.horizontalStyle.copyWith(
|
||||
padding: EdgeInsets.all(20.w),
|
||||
),
|
||||
),
|
||||
direction: Axis.horizontal,
|
||||
title: const SizedBox.shrink(),
|
||||
body: SfDateRangePicker(
|
||||
onSelectionChanged: (date) {
|
||||
if (date.value is PickerDateRange) {
|
||||
final v = date.value as PickerDateRange;
|
||||
if (v.startDate == null || v.endDate == null) {
|
||||
return;
|
||||
}
|
||||
slectDateTime = [v.startDate!, v.endDate!];
|
||||
}
|
||||
},
|
||||
initialSelectedDates: [startTIme, endTime],
|
||||
selectionMode: DateRangePickerSelectionMode.range,
|
||||
headerHeight: 60.h,
|
||||
todayHighlightColor: theme.colorScheme.primary,
|
||||
backgroundColor: theme.colorScheme.background,
|
||||
headerStyle: DateRangePickerHeaderStyle(
|
||||
textStyle: theme.typography.xl,
|
||||
textAlign: TextAlign.center,
|
||||
backgroundColor: theme.colorScheme.background,
|
||||
),
|
||||
selectionColor: theme.colorScheme.primary,
|
||||
startRangeSelectionColor: theme.colorScheme.primary,
|
||||
endRangeSelectionColor: theme.colorScheme.primary,
|
||||
rangeSelectionColor: theme.colorScheme.mutedForeground,
|
||||
selectionTextStyle: theme.typography.sm.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
rangeTextStyle: theme.typography.sm,
|
||||
monthCellStyle: DateRangePickerMonthCellStyle(
|
||||
textStyle: theme.typography.sm,
|
||||
todayTextStyle: theme.typography.sm,
|
||||
weekendTextStyle: theme.typography.sm,
|
||||
),
|
||||
monthViewSettings: DateRangePickerMonthViewSettings(
|
||||
viewHeaderHeight: 50.h,
|
||||
showWeekNumber: true,
|
||||
weekNumberStyle: DateRangePickerWeekNumberStyle(
|
||||
textStyle: theme.typography.sm,
|
||||
backgroundColor: theme.colorScheme.mutedForeground,
|
||||
),
|
||||
viewHeaderStyle: DateRangePickerViewHeaderStyle(
|
||||
textStyle: theme.typography.base,
|
||||
),
|
||||
),
|
||||
).width(width).height(height * 0.6),
|
||||
actions: [
|
||||
FButton(
|
||||
label: Text(
|
||||
"确定",
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () {
|
||||
if (ObjectUtil.isEmptyList(slectDateTime)) {
|
||||
Toast.error(msg: "请选择日期范围");
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pop(slectDateTime);
|
||||
},
|
||||
).width(200.w),
|
||||
SizedBox(width: 30.w),
|
||||
FButton(
|
||||
style: FButtonStyle.destructive,
|
||||
label: Text(
|
||||
"取消",
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () => Navigator.of(context).pop(null),
|
||||
).width(200.w),
|
||||
],
|
||||
),
|
||||
start: DateTime(2024),
|
||||
today: DateTime(2024, 7, 15),
|
||||
end: DateTime(2030),
|
||||
);
|
||||
}
|
||||
@@ -28,13 +28,14 @@ Future<bool> appMessageDialog(BuildContext context, String msg) async {
|
||||
label: Text('取消', style: theme.typography.base),
|
||||
onPress: () => Navigator.of(context).pop(false)),
|
||||
FButton(
|
||||
label: Text(
|
||||
'确定',
|
||||
style: theme.typography.base.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Text(
|
||||
'确定',
|
||||
style: theme.typography.base.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
onPress: () => Navigator.of(context).pop(true)),
|
||||
),
|
||||
onPress: () => Navigator.of(context).pop(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ Widget appPage(
|
||||
return <Widget>[
|
||||
<Widget>[
|
||||
Text(
|
||||
"共 $total 条",
|
||||
"每页$pageSize条,共$total条",
|
||||
style: theme.typography.lg.copyWith(
|
||||
fontWeight: theme.typography.xl8.fontWeight,
|
||||
color: theme.colorScheme.primary,
|
||||
|
||||
@@ -122,9 +122,6 @@ mixin OrderMixin {
|
||||
Future<void> getProduct({
|
||||
String classifyCode = "-1",
|
||||
}) async {
|
||||
if (hourType.value != appController.hourType.value) {
|
||||
hourType.value = appController.hourType.value;
|
||||
}
|
||||
final list = await appController.dataBase.getProductDao.getAll(
|
||||
classifyCode,
|
||||
hourType.value.code,
|
||||
|
||||
@@ -38,12 +38,17 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
|
||||
final app = Get.find<AppControl>();
|
||||
|
||||
final payTypeRadioC = FRadioSelectGroupController<OrderPayDisplayType>();
|
||||
|
||||
Rxn<ServiceUser?> payUser = Rxn(null);
|
||||
|
||||
Rxn<OrderPayType> orderPayType = Rxn(OrderPayType.face);
|
||||
|
||||
Rxn<OrderPayDisplayType> orderPayDisplayType = Rxn(OrderPayDisplayType.face);
|
||||
|
||||
RxList<OrderPayDisplayType> usePayDisplayTypeList =
|
||||
<OrderPayDisplayType>[].obs;
|
||||
|
||||
Rxn<OrderType> orderType = Rxn(OrderType.below);
|
||||
|
||||
RxBool isRecognition = RxBool(false);
|
||||
@@ -59,6 +64,34 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
// 人脸识别回调锁
|
||||
bool _faceCallbackLock = false;
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
if (appSetting.defaultPayDisplayType != null) {
|
||||
payTypeRadioC.value = {appSetting.defaultPayDisplayType!};
|
||||
}
|
||||
if (!ObjectUtil.isEmptyList(appSetting.usePayDisplayType)) {
|
||||
usePayDisplayTypeList.value = appSetting.usePayDisplayType!;
|
||||
}
|
||||
// 监听支付方式变化
|
||||
payTypeRadioC.addValueListener((v) {
|
||||
final payType = OrderPayDisplayType.values.fromCode(
|
||||
v.first.code,
|
||||
);
|
||||
if (payType == null || payType == orderPayDisplayType.value) {
|
||||
return;
|
||||
}
|
||||
orderPayDisplayType.value = payType;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
payTypeRadioC.dispose();
|
||||
}
|
||||
|
||||
_closeStatus() {
|
||||
payUser.value = null;
|
||||
isRecognition.value = false;
|
||||
@@ -427,12 +460,6 @@ class SelectPayTypeDialogController extends GetxController {
|
||||
Future<void> selectPayTypeDialog(BuildContext context) async {
|
||||
final payTypeC = Get.find<SelectPayTypeDialogController>();
|
||||
final payUser = payTypeC.payUser.value;
|
||||
payTypeC.orderPayType.value = OrderPayType.face;
|
||||
payTypeC.orderPayDisplayType.value = OrderPayDisplayType.face;
|
||||
|
||||
final controller = FRadioSelectGroupController<OrderPayDisplayType>(
|
||||
value: payTypeC.orderPayDisplayType.value,
|
||||
);
|
||||
|
||||
final theme = FTheme.of(context);
|
||||
final screenWidth = context.screenWidth;
|
||||
@@ -443,50 +470,59 @@ Future<void> selectPayTypeDialog(BuildContext context) async {
|
||||
direction: Axis.vertical,
|
||||
title: Text("选择支付方式", style: theme.typography.lg),
|
||||
body: <Widget>[
|
||||
FSelectGroup(
|
||||
controller: controller,
|
||||
style: theme.selectGroupStyle.copyWith(
|
||||
labelLayoutStyle: theme.selectGroupStyle.labelLayoutStyle.copyWith(
|
||||
childPadding: EdgeInsets.symmetric(
|
||||
vertical: 10.h,
|
||||
),
|
||||
),
|
||||
radioStyle: theme.selectGroupStyle.radioStyle.copyWith(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
items: OrderPayDisplayType.values
|
||||
.map<FSelectGroupItem<OrderPayDisplayType>>(
|
||||
(v) => FSelectGroupItem.radio(
|
||||
value: v,
|
||||
label: Text(
|
||||
v.title,
|
||||
style: theme.typography.xl,
|
||||
),
|
||||
Obx(
|
||||
() => FSelectGroup(
|
||||
controller: payTypeC.payTypeRadioC,
|
||||
style: theme.selectGroupStyle.copyWith(
|
||||
labelLayoutStyle:
|
||||
theme.selectGroupStyle.labelLayoutStyle.copyWith(
|
||||
childPadding: EdgeInsets.symmetric(
|
||||
vertical: 10.h,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
radioStyle: theme.selectGroupStyle.radioStyle.copyWith(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 10.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
items: payTypeC.usePayDisplayTypeList
|
||||
.map<FSelectGroupItem<OrderPayDisplayType>>(
|
||||
(v) => FSelectGroupItem.radio(
|
||||
value: v,
|
||||
label: Text(
|
||||
v.title,
|
||||
style: theme.typography.xl,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
Obx(() {
|
||||
final payTypeCode = payTypeC.orderPayDisplayType.value?.code;
|
||||
if (payTypeCode == null) return const SizedBox.shrink();
|
||||
final payType = payTypeC.orderPayDisplayType.value;
|
||||
if (payType == null) return const SizedBox.shrink();
|
||||
const baseMsg = "请点击开始识别按钮";
|
||||
String msg = "";
|
||||
SvgAsset icon = FAssets.icons.bird;
|
||||
if (payTypeCode == "1") {
|
||||
msg = "$baseMsg,并让用户扫描二维码";
|
||||
icon = FAssets.icons.qrCode;
|
||||
}
|
||||
if (payTypeCode == "2") {
|
||||
msg = "$baseMsg,并让用户刷饭卡";
|
||||
icon = FAssets.icons.idCard;
|
||||
}
|
||||
if (payTypeCode == "3") {
|
||||
msg = "$baseMsg,并让用户进行刷脸";
|
||||
icon = FAssets.icons.scanFace;
|
||||
switch (payType) {
|
||||
case OrderPayDisplayType.qrCode:
|
||||
msg = "$baseMsg,并让用户扫描二维码";
|
||||
icon = FAssets.icons.qrCode;
|
||||
break;
|
||||
case OrderPayDisplayType.walletCard:
|
||||
msg = "$baseMsg,并让用户刷饭卡";
|
||||
icon = FAssets.icons.idCard;
|
||||
break;
|
||||
case OrderPayDisplayType.face:
|
||||
msg = "$baseMsg,并让用户进行刷脸";
|
||||
icon = FAssets.icons.scanFace;
|
||||
break;
|
||||
case OrderPayDisplayType.cash:
|
||||
msg = "请打开钱箱,放入现金";
|
||||
icon = FAssets.icons.circleDollarSign;
|
||||
break;
|
||||
}
|
||||
return <Widget>[
|
||||
FIcon(
|
||||
|
||||
@@ -17,10 +17,12 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
|
||||
StreamSubscription? mqUpdateListen;
|
||||
|
||||
final hourTypeC = FRadioSelectGroupController(
|
||||
final hourTypeC = FRadioSelectGroupController<String>(
|
||||
value: ProductHourType.morning.code,
|
||||
);
|
||||
|
||||
late SysSetting appSetting;
|
||||
|
||||
_initData() {
|
||||
update(["canteen_product"]);
|
||||
}
|
||||
@@ -36,12 +38,15 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
|
||||
appSetting = await AppSettingTool.getSysSetting();
|
||||
|
||||
// 打开副屏
|
||||
SubScreenPlugin.doubleScreenShow();
|
||||
SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubPage.name);
|
||||
|
||||
/// **************** start 组件初始化 start ****************
|
||||
hourType.value = app.hourType.value;
|
||||
hourType.value = appSetting.hourType ?? ProductHourType.morning;
|
||||
hourTypeC.value = {hourType.value.code};
|
||||
sysType = SysType.canteen;
|
||||
// 重置状态
|
||||
closeStatus();
|
||||
@@ -50,37 +55,40 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
/// **************** end 组件初始化 end ****************
|
||||
|
||||
/// **************** start 获取分类和商品 start ****************
|
||||
|
||||
await getClassify();
|
||||
await getProduct();
|
||||
|
||||
/// **************** end 获取分类和商品 end ****************
|
||||
|
||||
await _clearShopCard();
|
||||
|
||||
EasyLoading.dismiss();
|
||||
|
||||
hourTypeC.addValueListener((v) async {
|
||||
final currentHourType = ProductHourType.values.fromCode(
|
||||
v.first,
|
||||
);
|
||||
if (currentHourType == null) return;
|
||||
if (currentHourType == null) {
|
||||
return;
|
||||
}
|
||||
EasyLoading.show(
|
||||
status: '切换中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
hourType.value = currentHourType;
|
||||
app.hourType.value = currentHourType;
|
||||
appSetting.hourType = currentHourType;
|
||||
await getClassify();
|
||||
await getProduct();
|
||||
await _clearShopCard();
|
||||
await AppSettingTool.setSysSetting(appSetting);
|
||||
EasyLoading.dismiss();
|
||||
});
|
||||
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
if (hourType.value != app.hourType.value) {
|
||||
app.hourType.value = app.hourType.value;
|
||||
}
|
||||
_initData();
|
||||
}
|
||||
|
||||
@@ -106,7 +114,6 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
final payTypeC = Get.find<SelectPayTypeDialogController>();
|
||||
payTypeC.payUser.value = payUser.value;
|
||||
payTypeC.orderPayDisplayType.value = orderPayDisplayType.value;
|
||||
// payTypeSelectDialog();
|
||||
}
|
||||
|
||||
// |下单|点击购买
|
||||
@@ -180,9 +187,7 @@ class CanteenProductController extends GetxController with OrderMixin {
|
||||
void _listenPayTypeSelectCallback() {
|
||||
final payTypeSelect = Get.find<SelectPayTypeDialogController>();
|
||||
// |支付方式|点击|开始识别|
|
||||
payTypeSelect.onRecognition = () async {
|
||||
// await createSqlOrder();
|
||||
};
|
||||
payTypeSelect.onRecognition = () async {};
|
||||
// 识别出用户的回调
|
||||
payTypeSelect.onDiscernUser = (payUser) {
|
||||
if (payUser == null) return;
|
||||
|
||||
@@ -209,10 +209,12 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
},
|
||||
),
|
||||
).expanded(),
|
||||
orderAllPrice(
|
||||
context,
|
||||
totalPrice: controller.totalPrice.value,
|
||||
amountMealPrice: controller.amountMealPrice.value,
|
||||
Obx(
|
||||
() => orderAllPrice(
|
||||
context,
|
||||
totalPrice: controller.totalPrice.value,
|
||||
amountMealPrice: controller.amountMealPrice.value,
|
||||
),
|
||||
),
|
||||
<Widget>[
|
||||
SizedBox(height: 20.h),
|
||||
|
||||
@@ -8,22 +8,22 @@ import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
class OrderHistoryController extends GetxController {
|
||||
final appC = Get.find<AppControl>();
|
||||
|
||||
late SysSetting appSetting;
|
||||
|
||||
PrintManage get printManage => appC.printManage;
|
||||
|
||||
Rx<ProductHourType> hourType = Rx(ProductHourType.morning);
|
||||
|
||||
DateTime startOrderCreateTime = DateTime.now().subtract(
|
||||
const Duration(days: 7),
|
||||
);
|
||||
|
||||
DateTime endOrderCreateTime = DateTime.now().add(
|
||||
const Duration(days: 1),
|
||||
);
|
||||
|
||||
Rx<OrderStatus> currentTab = OrderStatus.total.obs;
|
||||
Rx<OrderStatus> currentStatus = OrderStatus.total.obs;
|
||||
|
||||
RxList<OrderHistoryTableItem> tabList = <OrderHistoryTableItem>[].obs;
|
||||
|
||||
// 选择的时间
|
||||
RxList<DateTime> selectDateTime = <DateTime>[
|
||||
DateTime.now(),
|
||||
DateTime.now().add(const Duration(days: 1)),
|
||||
].obs;
|
||||
|
||||
// table
|
||||
RxInt currentPage = 1.obs;
|
||||
|
||||
@@ -33,7 +33,7 @@ class OrderHistoryController extends GetxController {
|
||||
|
||||
RxList<OrderEntity> orderList = RxList([]);
|
||||
|
||||
final hourTypeC = FRadioSelectGroupController(
|
||||
var hourTypeC = FRadioSelectGroupController(
|
||||
value: ProductHourType.morning.code,
|
||||
);
|
||||
|
||||
@@ -41,15 +41,14 @@ class OrderHistoryController extends GetxController {
|
||||
update(["order_history"]);
|
||||
}
|
||||
|
||||
void onTap() {}
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
final app = Get.find<AppControl>();
|
||||
hourType.value = app.hourType.value;
|
||||
appSetting = await AppSettingTool.getSysSetting();
|
||||
hourType.value = appSetting.hourType ?? ProductHourType.morning;
|
||||
hourTypeC.value = {hourType.value.code};
|
||||
// tabs
|
||||
await getTableList();
|
||||
await getTotalList();
|
||||
await getOrder();
|
||||
|
||||
hourTypeC.addValueListener((v) async {
|
||||
@@ -62,8 +61,8 @@ class OrderHistoryController extends GetxController {
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
hourType.value = currentHourType;
|
||||
await getTableList();
|
||||
currentPage.value = 1;
|
||||
await getTotalList();
|
||||
await getOrder();
|
||||
EasyLoading.dismiss();
|
||||
});
|
||||
@@ -91,41 +90,52 @@ class OrderHistoryController extends GetxController {
|
||||
// 订单列表
|
||||
Future<void> getOrder() async {
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
final app = Get.find<AppControl>();
|
||||
final sysType = appSetting.sysType.name;
|
||||
final orderDao = app.dataBase.getOrderDao;
|
||||
final orderDao = appC.dataBase.getOrderDao;
|
||||
|
||||
String orderStatus = currentStatus.value.name;
|
||||
if (currentStatus.value == OrderStatus.total) {
|
||||
orderStatus = "-1";
|
||||
}
|
||||
|
||||
final list = await orderDao.findAll(
|
||||
currentTab.value.code,
|
||||
startOrderCreateTime,
|
||||
endOrderCreateTime,
|
||||
orderStatus,
|
||||
selectDateTime[0],
|
||||
selectDateTime[1],
|
||||
pageSize.value,
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
sysType,
|
||||
hourType.value.code,
|
||||
);
|
||||
final total = await orderDao.count(
|
||||
currentTab.value.code,
|
||||
startOrderCreateTime,
|
||||
endOrderCreateTime,
|
||||
orderStatus,
|
||||
selectDateTime[0],
|
||||
selectDateTime[1],
|
||||
sysType,
|
||||
hourType.value.code,
|
||||
);
|
||||
if (total == null) {
|
||||
totalPage.value = 1;
|
||||
} else {
|
||||
totalPage.value = (total / pageSize.value).ceil();
|
||||
}
|
||||
totalPage.value = total ?? 0;
|
||||
orderList.value = list;
|
||||
}
|
||||
|
||||
Future<void> doTab(OrderStatus i) async {
|
||||
if (i.code == currentTab.value.code) return;
|
||||
currentTab.value = i;
|
||||
if (i.code == currentStatus.value.code) return;
|
||||
currentStatus.value = i;
|
||||
currentPage.value = 1;
|
||||
await getOrder();
|
||||
}
|
||||
|
||||
Future<void> getTableList() async {
|
||||
Future<void> doDateRangeDate(List<DateTime>? dateTime) async {
|
||||
if (ObjectUtil.isEmptyList(dateTime)) {
|
||||
return;
|
||||
}
|
||||
selectDateTime.value = dateTime!;
|
||||
currentPage.value = 1;
|
||||
await getTotalList();
|
||||
await getOrder();
|
||||
}
|
||||
|
||||
Future<void> getTotalList() async {
|
||||
final total = await _getTotal();
|
||||
List<OrderHistoryTableItem> tabs = OrderStatus.values
|
||||
.map((v) => OrderHistoryTableItem(status: v))
|
||||
@@ -142,7 +152,6 @@ class OrderHistoryController extends GetxController {
|
||||
// 根据日期查询统计
|
||||
Future<Map<String, dynamic>> _getTotal() async {
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
final app = Get.find<AppControl>();
|
||||
Map<String, dynamic> map = {
|
||||
"pay": 0,
|
||||
"nonePay": 0,
|
||||
@@ -160,20 +169,20 @@ class OrderHistoryController extends GetxController {
|
||||
FROM order_record
|
||||
WHERE
|
||||
sysType = ?
|
||||
AND createTime BETWEEN ? AND ?
|
||||
AND strftime('%Y-%m-%d', createTime) BETWEEN ? AND ?
|
||||
""";
|
||||
final sysType = appSetting.sysType.name;
|
||||
List<Object?>? args = [
|
||||
sysType,
|
||||
startOrderCreateTime.millisecondsSinceEpoch,
|
||||
endOrderCreateTime.millisecondsSinceEpoch
|
||||
DateUtil.formatDate(selectDateTime[0], format: DateFormats.y_mo_d),
|
||||
DateUtil.formatDate(selectDateTime[1], format: DateFormats.y_mo_d),
|
||||
];
|
||||
// 组装where条件
|
||||
if (hourType.value.code != "-1") {
|
||||
totalSql += " AND hourType = ?";
|
||||
args.add(hourType.value.code);
|
||||
}
|
||||
final list = await app.dataBase.database.rawQuery(totalSql, args);
|
||||
final list = await appC.dataBase.database.rawQuery(totalSql, args);
|
||||
if (!ObjectUtil.isEmptyList(list)) {
|
||||
final map = list[0];
|
||||
if (ObjectUtil.isNotEmpty(map)) {
|
||||
|
||||
@@ -42,7 +42,8 @@ class OrderHistoryPage extends GetView<OrderHistoryController> {
|
||||
Obx(
|
||||
() => controller.tabList
|
||||
.map((v) {
|
||||
final active = v.status.code == controller.currentTab.value.code;
|
||||
final active =
|
||||
v.status.code == controller.currentStatus.value.code;
|
||||
return FButton(
|
||||
style: active ? FButtonStyle.primary : FButtonStyle.secondary,
|
||||
label: Text(
|
||||
@@ -62,11 +63,16 @@ class OrderHistoryPage extends GetView<OrderHistoryController> {
|
||||
.toList()
|
||||
.toRowSpace(space: 20.w),
|
||||
).scrollable(scrollDirection: Axis.horizontal).expanded(),
|
||||
appRadioHourTypeDialog(
|
||||
context,
|
||||
controller.hourTypeC,
|
||||
).width(300.w),
|
||||
].toRow();
|
||||
// 用餐时间段
|
||||
appRadioHourTypeDialog(context, controller.hourTypeC).width(300.w),
|
||||
SizedBox(width: 30.w),
|
||||
// 用餐时间
|
||||
Obx(() => appDatePicker(
|
||||
context,
|
||||
datetimeRange: controller.selectDateTime,
|
||||
onChnage: (dateList) => controller.doDateRangeDate(dateList),
|
||||
)).width(400.w),
|
||||
].toRow(mainAxisAlignment: MainAxisAlignment.center);
|
||||
}
|
||||
|
||||
Widget _buildTable(BuildContext context) {
|
||||
|
||||
@@ -80,7 +80,7 @@ class PanelController extends GetxController {
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final id = sysSetting.serviceMerchantId;
|
||||
if (ObjectUtil.isEmpty(id)) {
|
||||
Toast.base(msg: "请前往设置绑定设备");
|
||||
Toast.error(msg: "请前往设置绑定设备");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -19,14 +20,12 @@ class SettingController extends GetxController {
|
||||
);
|
||||
|
||||
// 付款方式
|
||||
var globalPayTableC = FMultiSelectGroupController(
|
||||
values: OrderPayDisplayType.values.map((v) => v.code).toSet(),
|
||||
var globalPayTableC = FMultiSelectGroupController<String>(
|
||||
values: {},
|
||||
);
|
||||
|
||||
// 默认付款方式
|
||||
var defaultGlobalPayTableC = FRadioSelectGroupController<String>(
|
||||
value: OrderPayDisplayType.face.code,
|
||||
);
|
||||
var defaultGlobalPayTableC = FRadioSelectGroupController<String>();
|
||||
|
||||
_initData() {
|
||||
update(["setting"]);
|
||||
@@ -39,6 +38,11 @@ class SettingController extends GetxController {
|
||||
title: "基本信息",
|
||||
type: SettingMenuType.baseInfo,
|
||||
),
|
||||
SettingMenu(
|
||||
prefixIcon: FAssets.icons.databaseBackup,
|
||||
title: "资源备份",
|
||||
type: SettingMenuType.backup,
|
||||
),
|
||||
SettingMenu(
|
||||
prefixIcon: FAssets.icons.refreshCw,
|
||||
title: "同步设置",
|
||||
@@ -49,11 +53,6 @@ class SettingController extends GetxController {
|
||||
title: "支付设置",
|
||||
type: SettingMenuType.paySetting,
|
||||
),
|
||||
SettingMenu(
|
||||
prefixIcon: FAssets.icons.databaseBackup,
|
||||
title: "资源备份",
|
||||
type: SettingMenuType.backup,
|
||||
),
|
||||
SettingMenu(
|
||||
prefixIcon: FAssets.icons.scanFace,
|
||||
title: "人脸管理",
|
||||
@@ -79,6 +78,26 @@ class SettingController extends GetxController {
|
||||
final appTheme = Get.find<AppThemeControl>();
|
||||
appTheme.setSizeScalar(fontSizeType);
|
||||
});
|
||||
globalPayTableC.addValueListener((v) async {
|
||||
List<OrderPayDisplayType> usePayList = [];
|
||||
for (final i in v) {
|
||||
final payType = OrderPayDisplayType.values.fromCode(
|
||||
i,
|
||||
);
|
||||
if (payType == null) continue;
|
||||
usePayList.add(payType);
|
||||
}
|
||||
sysSetting.value?.usePayDisplayType = usePayList;
|
||||
await AppSettingTool.setSysSetting(sysSetting.value!);
|
||||
});
|
||||
defaultGlobalPayTableC.addValueListener((v) async {
|
||||
final payType = OrderPayDisplayType.values.fromCode(
|
||||
v.first,
|
||||
);
|
||||
if (payType == null) return;
|
||||
sysSetting.value?.defaultPayDisplayType = payType;
|
||||
await AppSettingTool.setSysSetting(sysSetting.value!);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -213,6 +232,7 @@ class SettingController extends GetxController {
|
||||
EasyLoading.dismiss();
|
||||
} catch (e) {
|
||||
Toast.error(msg: "备份中sql失败");
|
||||
logger.e("|$_tag|备份中sqlerror:|$e|");
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
}
|
||||
@@ -222,13 +242,46 @@ class SettingController extends GetxController {
|
||||
Toast.success(msg: "当前日志为实时备份");
|
||||
}
|
||||
|
||||
Future<void> getSetting() async {
|
||||
sysSetting.value = await AppSettingTool.getSysSetting();
|
||||
userSetting.value = await AppSettingTool.getUserSetting();
|
||||
if (userSetting.value!.globalFontSize != null) {
|
||||
globalFontSizeC = FRadioSelectGroupController(
|
||||
value: SettingGlobalFontSize.xl3.code,
|
||||
);
|
||||
// sql恢复
|
||||
Future<void> recoverSql() async {
|
||||
EasyLoading.show(
|
||||
status: '恢复中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
try {
|
||||
await AppFileTool.useLastBackDatabase();
|
||||
EasyLoading.dismiss();
|
||||
Toast.success(msg: "sql恢复成功");
|
||||
EasyLoading.dismiss();
|
||||
} catch (e) {
|
||||
Toast.error(msg: "sql恢复失败");
|
||||
logger.e("|$_tag|sql恢复失败error:|$e|");
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getSetting() async {
|
||||
sysSetting.value = await AppSettingTool.getSysSetting();
|
||||
if (sysSetting.value!.globalFontSize != null) {
|
||||
globalFontSizeC.value = {sysSetting.value!.globalFontSize!.code};
|
||||
}
|
||||
if (!ObjectUtil.isEmptyList(sysSetting.value!.usePayDisplayType)) {
|
||||
globalPayTableC.value =
|
||||
sysSetting.value!.usePayDisplayType!.map((v) => v.code).toSet();
|
||||
}
|
||||
if (sysSetting.value!.defaultPayDisplayType != null) {
|
||||
defaultGlobalPayTableC.value = {
|
||||
sysSetting.value!.defaultPayDisplayType!.code
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> checkIsBind() async {
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
final id = sysSetting.serviceMerchantId;
|
||||
if (ObjectUtil.isEmpty(id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+39
-17
@@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/models/index.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/pages/setting/widgets/index.dart';
|
||||
|
||||
import 'index.dart';
|
||||
@@ -85,22 +86,43 @@ class SettingPage extends GetView<SettingController> {
|
||||
}
|
||||
|
||||
Widget _buildDetail(BuildContext context, SettingMenuType type) {
|
||||
switch (type) {
|
||||
case SettingMenuType.baseInfo:
|
||||
return settingBaseInfo(context);
|
||||
case SettingMenuType.syncSetting:
|
||||
return settingSync(context);
|
||||
case SettingMenuType.paySetting:
|
||||
return settingPay(context);
|
||||
case SettingMenuType.backup:
|
||||
return settingBackup(context);
|
||||
case SettingMenuType.faceSetting:
|
||||
return settingFace(context);
|
||||
case SettingMenuType.productSetting:
|
||||
return settingProduct(context);
|
||||
default:
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return FutureBuilder(
|
||||
future: controller.checkIsBind(),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final isBand = snapshot.data!;
|
||||
switch (type) {
|
||||
case SettingMenuType.baseInfo:
|
||||
return settingBaseInfo(context);
|
||||
case SettingMenuType.backup:
|
||||
return settingBackup(context);
|
||||
case SettingMenuType.syncSetting:
|
||||
if (!isBand) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return settingSync(context);
|
||||
case SettingMenuType.paySetting:
|
||||
if (!isBand) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return settingPay(context);
|
||||
case SettingMenuType.faceSetting:
|
||||
if (!isBand) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return settingFace(context);
|
||||
case SettingMenuType.productSetting:
|
||||
if (!isBand) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return settingProduct(context);
|
||||
default:
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -13,6 +13,7 @@ Widget settingBackup(BuildContext context) {
|
||||
final sys = controller.sysSetting.value;
|
||||
if (sys == null) return const SizedBox.shrink();
|
||||
return <Widget>[
|
||||
appDividerTitle(context, "备份"),
|
||||
FTile(
|
||||
prefixIcon: appPrefixIcon(context, FAssets.icons.user),
|
||||
suffixIcon: appSuffixIcon(context, FAssets.icons.files),
|
||||
@@ -32,6 +33,13 @@ Widget settingBackup(BuildContext context) {
|
||||
title: appPrefixTitle(context, "log备份"),
|
||||
onPress: () => controller.backupsLog(),
|
||||
),
|
||||
appDividerTitle(context, "恢复"),
|
||||
FTile(
|
||||
prefixIcon: appPrefixIcon(context, FAssets.icons.user),
|
||||
suffixIcon: appSuffixIcon(context, FAssets.icons.folderSync),
|
||||
title: appPrefixTitle(context, "sql恢复"),
|
||||
onPress: () => controller.recoverSql(),
|
||||
),
|
||||
].toColumnSpace(space: 20.h);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,26 +14,21 @@ Widget settingPay(BuildContext context) {
|
||||
final sys = controller.sysSetting.value;
|
||||
if (sys == null) return const SizedBox.shrink();
|
||||
return <Widget>[
|
||||
FSelectMenuTile.builder(
|
||||
FSelectMenuTile(
|
||||
groupController: controller.globalPayTableC,
|
||||
validator: (value) => value == null ? '请选择' : null,
|
||||
autoHide: true,
|
||||
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
|
||||
suffixIcon: appSuffixIcon(context, FAssets.icons.audioLines),
|
||||
title: appPrefixTitle(context, "使用支付方式"),
|
||||
menuTileBuilder: (context, index) {
|
||||
if (index >= OrderPayDisplayType.values.length) {
|
||||
return null;
|
||||
}
|
||||
final type = OrderPayDisplayType.values[index];
|
||||
menu: OrderPayDisplayType.values.map((v) {
|
||||
return FSelectTile(
|
||||
title: Text(
|
||||
type.title,
|
||||
v.title,
|
||||
style: theme.typography.xl,
|
||||
),
|
||||
value: type.code,
|
||||
value: v.code,
|
||||
);
|
||||
},
|
||||
}).toList(),
|
||||
details: ListenableBuilder(
|
||||
listenable: controller.globalPayTableC,
|
||||
builder: (context, _) {
|
||||
|
||||
@@ -70,10 +70,8 @@ class ProductManageController extends GetxController {
|
||||
sysType,
|
||||
currnetHourType,
|
||||
);
|
||||
if (findCount != null) {
|
||||
totalPage.value = (findCount / pageSize.value).ceil();
|
||||
}
|
||||
final list = await productDao.getCurrentDayAllPage(
|
||||
if (findCount != null) totalPage.value = findCount;
|
||||
final list = await productDao.getAllPage(
|
||||
"-1",
|
||||
currnetHourType,
|
||||
sysType,
|
||||
@@ -101,7 +99,7 @@ class ProductManageController extends GetxController {
|
||||
try {
|
||||
final isSure = await appMessageDialog(
|
||||
Get.context!,
|
||||
"是否${v.isDefault ? '设置为' : '取消'}默认菜品",
|
||||
"是否${v.isDefault ? '取消' : '设置为'}默认菜品",
|
||||
);
|
||||
if (!isSure) return;
|
||||
EasyLoading.show(
|
||||
@@ -151,58 +149,57 @@ Widget buildSearch(BuildContext context) {
|
||||
Widget buildList(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final productC = Get.find<ProductManageController>();
|
||||
return GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 8,
|
||||
mainAxisSpacing: 10.w,
|
||||
crossAxisSpacing: 10.w,
|
||||
childAspectRatio: 0.7,
|
||||
),
|
||||
itemCount: productC.productList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final v = productC.productList[index];
|
||||
return FCard(
|
||||
style: theme.cardStyle.copyWith(
|
||||
contentStyle: theme.cardStyle.contentStyle.copyWith(
|
||||
padding: EdgeInsets.all(0),
|
||||
return Obx(
|
||||
() => GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 8,
|
||||
mainAxisSpacing: 10.w,
|
||||
crossAxisSpacing: 10.w,
|
||||
childAspectRatio: 0.7,
|
||||
),
|
||||
itemCount: productC.productList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final v = productC.productList[index];
|
||||
return FCard(
|
||||
style: theme.cardStyle.copyWith(
|
||||
contentStyle: theme.cardStyle.contentStyle.copyWith(
|
||||
padding: EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
),
|
||||
image: appImg(v.image, width: double.infinity, height: 120.h),
|
||||
title: Text(v.name, maxLines: 2, style: theme.typography.base).center(),
|
||||
subtitle: appPrice(context, v.price.toString())
|
||||
.center()
|
||||
.paddingOnly(top: 10.h),
|
||||
child: <Widget>[
|
||||
Text("是否默认", style: theme.typography.sm),
|
||||
FSwitch(
|
||||
value: v.isDefault,
|
||||
onChange: (value) => productC.trigger(v),
|
||||
)
|
||||
].toRow(mainAxisAlignment: MainAxisAlignment.center),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 分页
|
||||
Widget buildPage(BuildContext context) {
|
||||
final productC = Get.find<ProductManageController>();
|
||||
return appPage(
|
||||
context,
|
||||
pageNo: productC.currentPage.value,
|
||||
pageSize: productC.pageSize.value,
|
||||
total: productC.totalPage.value * productC.pageSize.value,
|
||||
onPageChanged: (pageNo) => productC.doPage(page: pageNo),
|
||||
image: appImg(v.image, width: double.infinity, height: 120.h),
|
||||
title:
|
||||
Text(v.name, maxLines: 2, style: theme.typography.base).center(),
|
||||
subtitle: appPrice(context, v.price.toString())
|
||||
.center()
|
||||
.paddingOnly(top: 10.h),
|
||||
child: <Widget>[
|
||||
Text("是否默认", style: theme.typography.sm),
|
||||
FSwitch(
|
||||
value: v.isDefault,
|
||||
onChange: (value) => productC.trigger(v),
|
||||
)
|
||||
].toRow(mainAxisAlignment: MainAxisAlignment.center),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget settingProduct(BuildContext context) {
|
||||
Get.put<ProductManageController>(
|
||||
final productC = Get.put<ProductManageController>(
|
||||
ProductManageController(),
|
||||
);
|
||||
return <Widget>[
|
||||
buildSearch(context),
|
||||
buildList(context).expanded(),
|
||||
buildPage(context),
|
||||
Obx(
|
||||
() => appPage(
|
||||
context,
|
||||
pageNo: productC.currentPage.value,
|
||||
pageSize: productC.pageSize.value,
|
||||
total: productC.totalPage.value,
|
||||
onPageChanged: (pageNo) => productC.doPage(page: pageNo),
|
||||
),
|
||||
),
|
||||
].toColumnSpace(space: 10.h);
|
||||
}
|
||||
@@ -1151,6 +1151,22 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "59b6d2a7deacade6129d2f15615ca49ed56278fea055cd2e52cace78a343dd5e"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "28.2.11"
|
||||
syncfusion_flutter_datepicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_datepicker
|
||||
sha256: "7e598b8933d906ef7a3b8f47c59e942409f71c8e59e3d1b88e67acc9eea48817"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "28.2.11"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -30,6 +30,8 @@ dependencies:
|
||||
data_table_2: ^2.5.18
|
||||
# 分页
|
||||
number_pagination: ^1.1.6
|
||||
# 日期选择
|
||||
syncfusion_flutter_datepicker: ^28.2.11
|
||||
|
||||
# 权限判断
|
||||
permission_handler: ^11.4.0
|
||||
|
||||
Reference in new issue
Block a user