This commit is contained in:
2026-07-12 04:33:48 +08:00
parent f8a90ad305
commit e7ce0f7bae
151 changed files with 2765 additions and 2947 deletions

View File

@@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_wisetronic/models/product.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hive/hive.dart';
import 'package:intl/intl.dart';
import 'package:path/path.dart' as path;
import 'package:universal_io/io.dart';
@@ -28,6 +27,7 @@ import '../store/actions.dart';
import '../store/store.dart';
import 'http_util.dart';
import 'util_web.dart' if (dart.library.io) 'util_io.dart';
import 'package:shared_preferences/shared_preferences.dart';
typedef void OnSuccess(Response response);
typedef void OnError(dynamic error);
@@ -37,16 +37,25 @@ typedef void OnOk();
typedef void OnLoadImageError();
class Utils {
static StreamSubscription onProductWillAddToCartSubscription;
static StreamSubscription onProductWillRemoveFromCartSubscription;
static final Utils _utils = Utils._internal();
static SharedPreferences? prefs;
static StreamSubscription? onProductWillAddToCartSubscription;
static StreamSubscription? onProductWillRemoveFromCartSubscription;
factory Utils() {
return _utils;
}
Utils._internal();
init() async {
prefs = await SharedPreferences.getInstance();
onProductWillAddToCartSubscription =
eventBus.on<OnProductWillAddToCart>().listen((event) {
CartInfo cartInfo =
CartInfo? cartInfo =
getCartInfoByBusiness(store.state.cartInfos, event.business);
if (cartInfo == null || cartInfo.productList.length == 0) {
if (cartInfo == null || cartInfo.productList!.length == 0) {
cartInfo = CartInfo();
cartInfo.id = 0;
cartInfo.amountPaid = 0.0;
@@ -57,7 +66,7 @@ class Utils {
id: 0,
price: event.price,
product: event.product,
name: event.product.name,
name: event.product.name!,
description: event.description,
quantity: 1.0);
cartInfo.productList = [lineItem];
@@ -67,15 +76,15 @@ class Utils {
eventBus.fire(new OnCartInfoUpdated());
print('#1');
} else {
if (event.product.productAttributes.length > 0) {
if (event.product.productAttributes!.length > 0) {
CartLineItem lineItem = newCartLineItem(
id: 0,
price: event.price,
product: event.product,
name: event.product.name,
name: event.product.name!,
description: event.description,
quantity: 1.0);
cartInfo.productList.add(lineItem);
cartInfo.productList!.add(lineItem);
addSubproductToCard(cartInfo, lineItem);
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
store.state.cartInfos, cartInfo)));
@@ -83,8 +92,8 @@ class Utils {
eventBus.fire(new OnCartInfoUpdated());
} else {
int found = -1;
for (var i = 0; i < cartInfo.productList.length; i++) {
if (event.product.id == cartInfo.productList[i].product.id) {
for (var i = 0; i < cartInfo.productList!.length; i++) {
if (event.product.id == cartInfo.productList![i].product!.id) {
found = i;
break;
}
@@ -94,18 +103,18 @@ class Utils {
id: 0,
price: event.price,
product: event.product,
name: event.product.name,
name: event.product.name!,
description: event.description,
quantity: 1.0);
cartInfo.productList.add(lineItem);
cartInfo.productList!.add(lineItem);
addSubproductToCard(cartInfo, lineItem);
store.dispatch(new UpdateCartInfo(addCartInfoToCartInfoList(
store.state.cartInfos, cartInfo)));
print('#3');
eventBus.fire(new OnCartInfoUpdated());
} else {
if (cartInfo.productList[found].quantity + 1.0 >
event.product.leftNum) {
if (cartInfo.productList![found].quantity! + 1.0 >
event.product.leftNum!) {
// Fluttertoast.showToast(
// msg: S.of(context).product_insufficient,
// toastLength: Toast.LENGTH_SHORT,
@@ -113,8 +122,8 @@ class Utils {
// backgroundColor: Colors.red,
// textColor: Colors.white);
} else {
cartInfo.productList[found].quantity += 1;
addSubproductQty(cartInfo, cartInfo.productList[found]);
cartInfo.productList![found].quantity = cartInfo.productList![found].quantity! + 1;
addSubproductQty(cartInfo, cartInfo.productList![found]);
store.dispatch(new UpdateCartInfo(
addCartInfoToCartInfoList(
store.state.cartInfos, cartInfo)));
@@ -127,41 +136,41 @@ class Utils {
});
onProductWillRemoveFromCartSubscription =
eventBus.on<OnProductWillRemoveFromCart>().listen((event) {
CartInfo cartInfo =
CartInfo? cartInfo =
getCartInfoByBusiness(store.state.cartInfos, event.business);
if (cartInfo != null) {
if (cartInfo.productList.length > 0) {
if (cartInfo.productList!.length > 0) {
if (event.productListIndex != -1) {
if (cartInfo.productList[event.productListIndex].quantity <= 1) {
String uuid = cartInfo.productList[event.productListIndex].uuid;
cartInfo.productList.removeAt(event.productListIndex);
if (cartInfo.productList![event.productListIndex].quantity! <= 1) {
String uuid = cartInfo.productList![event.productListIndex].uuid!;
cartInfo.productList!.removeAt(event.productListIndex);
removeSubproduct(cartInfo, uuid);
} else {
cartInfo.productList[event.productListIndex].quantity -= 1;
addSubproductQty(cartInfo, cartInfo.productList[event.productListIndex], remove: true);
cartInfo.productList![event.productListIndex].quantity = cartInfo.productList![event.productListIndex].quantity! - 1;
addSubproductQty(cartInfo, cartInfo.productList![event.productListIndex], remove: true);
}
} else {
int productListIndex = -1;
for (var i = 0; i < cartInfo.productList.length; i++) {
if (cartInfo.productList[i].product.id == event.product.id) {
for (var i = 0; i < cartInfo.productList!.length; i++) {
if (cartInfo.productList![i].product!.id == event.product.id) {
productListIndex = i;
break;
}
}
if (productListIndex != -1) {
if (cartInfo.productList[productListIndex].quantity <= 1) {
String uuid = cartInfo.productList[productListIndex].uuid;
cartInfo.productList.removeAt(productListIndex);
if (cartInfo.productList![productListIndex].quantity! <= 1) {
String uuid = cartInfo.productList![productListIndex].uuid!;
cartInfo.productList!.removeAt(productListIndex);
removeSubproduct(cartInfo, uuid);
} else {
cartInfo.productList[productListIndex].quantity -= 1;
addSubproductQty(cartInfo, cartInfo.productList[productListIndex], remove: true);
cartInfo.productList![productListIndex].quantity = cartInfo.productList![productListIndex].quantity! - 1;
addSubproductQty(cartInfo, cartInfo.productList![productListIndex], remove: true);
}
}
}
}
if (cartInfo.productList.length <= 0) {
if (cartInfo.productList!.length <= 0) {
store.dispatch(UpdateCartInfo(removeCartInfoFromCartInfoList(
store.state.cartInfos, cartInfo)));
} else {
@@ -211,7 +220,7 @@ class Utils {
return false;
}
static Map<String, dynamic> stringToJson(String string) {
static Map<String, dynamic>? stringToJson(String? string) {
if (string == null || string.isEmpty) {
return null;
}
@@ -244,10 +253,6 @@ class Utils {
return platformName;
}
static Future<Box> getBox() async {
return Util.getBox();
}
static Widget imageLoadingIndicator(
{double width = 30.0, double height = 30.0}) {
return SizedBox(
@@ -365,7 +370,7 @@ class Utils {
);
}
static showLoadingDialog(BuildContext context, {String message}) {
static showLoadingDialog(BuildContext context, {String? message}) {
showDialog(
context: context,
barrierDismissible: false,
@@ -468,46 +473,45 @@ class Utils {
}
static void getCurrentUser() {
getBox().then((box) {
int userId = box.get(Constants.KEY_USER_ID, defaultValue: 0);
String accessToken =
box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
if (userId == 0 || accessToken.isEmpty) {
eventBus.fire(new OnGetCurrentUserFailed(Error()));
} else {
HttpUtil.httpGet(
'v1/users/$userId',
queryParameters: {},
businessId: Constants.BUSINESS_ID,
).then((value) {
User user = User.fromJson(value);
store.dispatch(UpdateCurrentUser(user));
eventBus.fire(OnCurrentUserUpdated());
}).catchError((err) {
eventBus.fire(new OnGetCurrentUserFailed(err));
});
}
}).catchError((err) {
eventBus.fire(new OnGetCurrentUserFailed(err));
});
if (store.state.user != null) {
eventBus.fire(OnCurrentUserUpdated());
return;
}
int? userId = prefs?.getInt(Constants.KEY_USER_ID) ?? 0;
String? accessToken = prefs?.getString(Constants.KEY_ACCESS_TOKEN) ?? '';
if (userId == 0 || accessToken.isEmpty) {
eventBus.fire(new OnGetCurrentUserFailed(Error()));
} else {
HttpUtil.httpGet(
'v1/users/$userId',
queryParameters: {},
businessId: Constants.BUSINESS_ID,
).then((value) {
User user = User.fromJson(value);
store.dispatch(UpdateCurrentUser(user));
eventBus.fire(OnCurrentUserUpdated());
}).catchError((err) {
eventBus.fire(new OnGetCurrentUserFailed(err));
});
}
}
static void showMessageDialog(BuildContext context, dynamic error,
{String title, List<Widget> actions, OnOk onOk}) {
{String? title, List<Widget>? actions, OnOk? onOk}) {
String message = '';
print('error $error');
if (error is DioError && error.response != null) {
if (error.response.data['message'] != null) {
message = error.response.data['message'];
} else if (error.response.data['error'] != null) {
if (error.response.data['error'] is String) {
message = error.response.data['error'];
} else if (error.response.data['error']['errmsg'] != null) {
message = error.response.data['error']['errmsg'];
} else if (error.response.data['error']['message'] != null) {
message = error.response.data['error']['message'];
if (error is DioException && error.response != null) {
if (error.response!.data['message'] != null) {
message = error.response!.data['message'];
} else if (error.response!.data['error'] != null) {
if (error.response!.data['error'] is String) {
message = error.response!.data['error'];
} else if (error.response!.data['error']['errmsg'] != null) {
message = error.response!.data['error']['errmsg'];
} else if (error.response!.data['error']['message'] != null) {
message = error.response!.data['error']['message'];
} else {
message = error.response.data.toString();
message = error.response!.data.toString();
}
}
} else if (error is String) {
@@ -540,20 +544,15 @@ class Utils {
}
static Future<List<int>> getLastVisit() async {
Box box = await getBox();
List<dynamic> lastVisit =
json.decode(box.get(Constants.KEY_LAST_VISIT, defaultValue: '[]'));
json.decode(prefs?.getString(Constants.KEY_LAST_VISIT) ?? '[]');
List<int> lv = lastVisit.map((e) => e as int).toList();
store.dispatch(UpdateLastVisit(lv));
return lv;
}
static void saveLastVisit(List<int> lastVisit) {
getBox().then((box) {
box.put(Constants.KEY_LAST_VISIT, lastVisit.toString());
}).catchError((error) {
print('Error occurred: $error');
});
prefs?.setString(Constants.KEY_LAST_VISIT, lastVisit.toString());
}
static String utcDatetimeStringToLocalDatetimeString(
@@ -656,26 +655,26 @@ class Utils {
}
}
static CartInfo getCartInfoByBusiness(
List<CartInfo> cartInfos, Business business) {
static CartInfo? getCartInfoByBusiness(
List<CartInfo>? cartInfos, Business business) {
if (cartInfos == null || cartInfos.length <= 0) {
return null;
}
for (var i = 0; i < cartInfos.length; i++) {
if (cartInfos[i].businessInfo.id == business.id) {
if (cartInfos[i].businessInfo!.id == business.id) {
return cartInfos[i];
}
}
return null;
}
static CartInfo getCartInfoByBusinessId(
List<CartInfo> cartInfos, int businessId) {
static CartInfo? getCartInfoByBusinessId(
List<CartInfo>? cartInfos, int businessId) {
if (cartInfos == null || cartInfos.length <= 0) {
return null;
}
for (var i = 0; i < cartInfos.length; i++) {
if (cartInfos[i].businessInfo.id == businessId) {
if (cartInfos[i].businessInfo!.id == businessId) {
return cartInfos[i];
}
}
@@ -683,13 +682,13 @@ class Utils {
}
static List<CartInfo> addCartInfoToCartInfoList(
List<CartInfo> cartInfos, CartInfo cartInfo) {
List<CartInfo>? cartInfos, CartInfo cartInfo) {
if (cartInfos == null || cartInfos.length <= 0) {
cartInfos = [cartInfo];
} else {
bool found = false;
for (var i = 0; i < cartInfos.length; i++) {
if (cartInfos[i].businessInfo.id == cartInfo.businessInfo.id) {
if (cartInfos[i].businessInfo!.id == cartInfo.businessInfo!.id) {
cartInfos[i] = cartInfo;
found = true;
break;
@@ -699,22 +698,19 @@ class Utils {
cartInfos.add(cartInfo);
}
}
Utils.getBox().then((box) {
box.put(Constants.KEY_CARTINFOS, cartInfos.toString());
}).catchError((error) {
print('Error occurred: $error');
});
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
return cartInfos;
}
static List<CartInfo> removeCartInfoFromCartInfoList(
List<CartInfo> cartInfos, CartInfo cartInfo) {
List<CartInfo>? cartInfos, CartInfo? cartInfo) {
if (cartInfos == null || cartInfos.length <= 0 || cartInfo == null) {
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
return [];
}
int removeIndex = -1;
for (var i = 0; i < cartInfos.length; i++) {
if (cartInfo.businessInfo.id == cartInfos[i].businessInfo.id) {
if (cartInfo.businessInfo!.id == cartInfos[i].businessInfo!.id) {
removeIndex = i;
break;
}
@@ -722,17 +718,13 @@ class Utils {
if (removeIndex != -1) {
cartInfos.removeAt(removeIndex);
}
getBox().then((box) {
box.put(Constants.KEY_CARTINFOS, cartInfos.toString());
}).catchError((error) {
print('Error occurred: $error');
});
prefs?.setString(Constants.KEY_CARTINFOS, cartInfos.toString());
return cartInfos;
}
static void clearCart(BuildContext context, CartInfo cartInfo,
{OnComplete onComplete}) {
if (cartInfo != null && cartInfo.productList.length > 0) {
{OnComplete? onComplete}) {
if (cartInfo != null && cartInfo.productList!.length > 0) {
showDialog(
context: context,
builder: (BuildContext context) {
@@ -766,7 +758,7 @@ class Utils {
}
static void requireLogin(BuildContext context,
{String returnUrl, bool replace = true, int delayMilliseconds = 400}) {
{String? returnUrl, bool replace = true, int delayMilliseconds = 400}) {
Future.delayed(Duration(milliseconds: delayMilliseconds), () {
if (returnUrl != null) {
store.dispatch(UpdateRedirectRoute(returnUrl));
@@ -775,9 +767,9 @@ class Utils {
});
}
static String getFirstNumberFromString(String numString) {
static String? getFirstNumberFromString(String numString) {
final intInStr = RegExp(r'\d+');
return intInStr.firstMatch(numString).group(0);
return intInStr.firstMatch(numString)?.group(0);
}
static void loadProducts(int businessId, int categoryId, int page, bool more,
@@ -845,7 +837,7 @@ class Utils {
}
}
static String getWeekDayName(BuildContext context, int timestamp, bool shortName) {
static String? getWeekDayName(BuildContext context, int timestamp, bool shortName) {
DateTime date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
switch(date.weekday) {
case 1:
@@ -854,61 +846,54 @@ class Utils {
} else {
return S.of(context).monday;
}
break;
case 2:
if (shortName) {
return S.of(context).tue;
} else {
return S.of(context).tuesday;
}
break;
case 3:
if (shortName) {
return S.of(context).wed;
} else {
return S.of(context).wednesday;
}
break;
case 4:
if (shortName) {
return S.of(context).thu;
} else {
return S.of(context).thursday;
}
break;
case 5:
if (shortName) {
return S.of(context).fri;
} else {
return S.of(context).friday;
}
break;
case 6:
if (shortName) {
return S.of(context).sat;
} else {
return S.of(context).saturday;
}
break;
case 7:
if (shortName) {
return S.of(context).sun;
} else {
return S.of(context).sunday;
}
break;
}
}
static void stripePaymentIntent(Order order, String customerId, String paymentMethodId, String cardType,
static void stripePaymentIntent(Order order, String? customerId, String paymentMethodId, String cardType,
OnSuccess onSuccess, OnError onError,
{
String cardBrand,
String cardCountry,
int cardExpMonth,
int cardExpYear,
String cardFunding,
String cardLast4,
String? cardBrand,
String? cardCountry,
int? cardExpMonth,
int? cardExpYear,
String? cardFunding,
String? cardLast4,
}) {
HttpUtil.httpPost('v1/stripe-payment-intent',
@@ -919,12 +904,12 @@ class Utils {
'customer_id': customerId == null ? '' : customerId,
'payment_method_id': paymentMethodId,
'payment_method_type': cardType,
'card_brand': cardBrand,
'card_country': cardCountry,
'card_exp_month': cardExpMonth,
'card_exp_year': cardExpYear,
'card_funding': cardFunding,
'card_last4': cardLast4,
'card_brand': cardBrand ?? '',
'card_country': cardCountry ?? '',
'card_exp_month': cardExpMonth ?? 0,
'card_exp_year': cardExpYear ?? 0,
'card_funding': cardFunding ?? '',
'card_last4': cardLast4 ?? '',
},
isFormData: true,
).catchError(onError);
@@ -945,8 +930,8 @@ class Utils {
static int getProductLineInOrder(CartInfo cartInfo) {
int qty = 0;
for (CartLineItem lineItem in cartInfo.productList) {
if (lineItem.product.id != null) {
for (CartLineItem lineItem in cartInfo.productList!) {
if (lineItem.product?.id != null) {
qty += 1;
}
}
@@ -954,10 +939,10 @@ class Utils {
}
static void orderAgain(BuildContext context, CartInfo cartInfo) {
cartInfo.productList.removeWhere((element) => element.product == null || element.product.id == null);
cartInfo.productList!.removeWhere((element) => element.product == null || element.product!.id == null);
store.dispatch(UpdateCartInfo(Utils.addCartInfoToCartInfoList(store.state.cartInfos, cartInfo)));
eventBus.fire(new OnCartInfoUpdated());
Routes.router.navigateTo(context, '/checkout/${cartInfo.businessInfo.id}');
Routes.router.navigateTo(context, '/checkout/${cartInfo.businessInfo!.id}');
}
static String getOrderStatus(BuildContext context, int statusCode) {
@@ -978,42 +963,42 @@ class Utils {
}
static CartLineItem newCartLineItem(
{int id,
double price,
Product product,
String name,
String description,
double quantity,
String parentUuid,
{int? id,
double? price,
Product? product,
String? name,
String? description,
double? quantity,
String? parentUuid,
}) {
CartLineItem lineItem = CartLineItem();
lineItem.unitPrice = price;
lineItem.product = product;
lineItem.name = product.name;
lineItem.name = product?.name ?? '';
lineItem.description = description;
lineItem.quantity = quantity;
lineItem.parentUuid = parentUuid;
lineItem.parentUuid = parentUuid ?? '';
return lineItem;
}
static void addSubproductToCard(CartInfo cartInfo, CartLineItem lineItem) {
if (lineItem.product.subproducts.length > 0) {
for (int j = 0; j < lineItem.product.subproducts.length; j++) {
cartInfo.productList.add(
if (lineItem.product!.subproducts!.length > 0) {
for (int j = 0; j < lineItem.product!.subproducts!.length; j++) {
cartInfo.productList!.add(
newCartLineItem(
id: 0,
price: 0.0,
product: Product(
lineItem.product.subproducts[j].product.id,
lineItem.product.businessId,
lineItem.product.subproducts[j].product.name,
lineItem.product.subproducts[j].product.price,
lineItem.product.subproducts[j].product.description,
lineItem.product.subproducts[j].product.image,
lineItem.product.subproducts[j].product.productAttributes
lineItem.product!.subproducts![j].product.id,
lineItem.product!.businessId!,
lineItem.product!.subproducts![j].product.name,
lineItem.product!.subproducts![j].product.price,
lineItem.product!.subproducts![j].product.description,
lineItem.product!.subproducts![j].product.image,
lineItem.product!.subproducts![j].product.productAttributes
),
name: lineItem.product.subproducts[j].product.name,
description: lineItem.product.subproducts[j].product.description,
name: lineItem.product!.subproducts![j].product.name,
description: lineItem.product!.subproducts![j].product.description,
quantity: 1.0,
parentUuid: lineItem.uuid
)
@@ -1024,16 +1009,16 @@ class Utils {
static void addSubproductQty(CartInfo cartInfo, CartLineItem lineItem,
{bool remove = false}) {
if (lineItem.product.subproducts.length > 0) {
for (var i = 0; i < cartInfo.productList.length; i++) {
CartLineItem lineItem1 = cartInfo.productList[i];
if (lineItem.product!.subproducts!.length > 0) {
for (var i = 0; i < cartInfo.productList!.length; i++) {
CartLineItem lineItem1 = cartInfo.productList![i];
if (lineItem1.parentUuid == lineItem.uuid) {
for (var j = 0; j < lineItem.product.subproducts.length; j++) {
if (lineItem.product.subproducts[j].product.id == lineItem1.product.id) {
for (var j = 0; j < lineItem.product!.subproducts!.length; j++) {
if (lineItem.product!.subproducts![j].product.id == lineItem1.product!.id) {
if (remove) {
lineItem1.quantity -= lineItem.product.subproducts[j].quantity;
lineItem1.quantity = lineItem1.quantity! - lineItem.product!.subproducts![j].quantity;
} else {
lineItem1.quantity += lineItem.product.subproducts[j].quantity;
lineItem1.quantity = lineItem1.quantity! + lineItem.product!.subproducts![j].quantity;
}
break;
}
@@ -1044,7 +1029,7 @@ class Utils {
}
static void removeSubproduct(CartInfo cartInfo, String uuid) {
cartInfo.productList.removeWhere((element) => element.parentUuid == uuid);
cartInfo.productList!.removeWhere((element) => element.parentUuid == uuid);
}
static void openEmail(String email) async {
@@ -1069,7 +1054,7 @@ class Utils {
}
}
static Widget buildLine(String name, dynamic value, {double nameSize, double valueSize}) {
static Widget buildLine(String name, dynamic value, {double? nameSize, double? valueSize}) {
Row row = Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -1119,7 +1104,7 @@ class Utils {
}
class RuntimeError extends Error {
final int code;
final int? code;
final String message;
RuntimeError(this.message, {this.code});
String toString() => "Runtime Error: $message";