feat : change app inspector and exception handling

This commit is contained in:
2025-07-12 17:06:29 +03:30
parent e52674de37
commit 0fc16569a6
24 changed files with 472 additions and 322 deletions

View File

@@ -4,7 +4,7 @@ import 'package:rasadyar_core/core.dart';
import '../di/chicken_di.dart';
import 'constant.dart';
class DioRemoteManager {
/*class DioRemoteManager {
DioRemote? _currentClient;
ApiEnvironment? _currentEnv;
@@ -28,6 +28,6 @@ class DioRemoteManager {
}
ApiEnvironment? get currentEnv => _currentEnv;
}
}*/

View File

@@ -1,4 +1,3 @@
import 'package:rasadyar_auth/data/di/auth_di.dart';
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
import 'package:rasadyar_chicken/data/repositories/chicken_repository_imp.dart';
import 'package:rasadyar_core/core.dart';
@@ -8,10 +7,30 @@ GetIt diChicken = GetIt.instance;
Future<void> setupChickenDI() async {
var tokenService = Get.find<TokenStorageService>();
diAuth.registerLazySingleton<DioRemote>(() => DioRemote(baseUrl: tokenService.baseurl.value));
final dioRemote = diAuth.get<DioRemote>();
diChicken.registerLazySingleton<AppInterceptor>(
() => AppInterceptor(
refreshTokenCallback: () async {},
saveTokenCallback: (String newToken) async {
await tokenService.saveAccessToken(newToken); // ذخیره توکن جدید
},
clearTokenCallback: () async {
await tokenService.deleteTokens();
},
),
instanceName: 'chickenInterceptor',
);
tokenService.getBaseUrl();
diChicken.registerLazySingleton<DioRemote>(() {
return DioRemote(
baseUrl: tokenService.baseurl.value,
interceptors: diChicken.get<AppInterceptor>(instanceName: 'chickenInterceptor'),
);
}, instanceName: 'chickenDioRemote');
final dioRemote = diChicken.get<DioRemote>(instanceName: 'chickenDioRemote');
await dioRemote.init();
diAuth.registerLazySingleton<ChickenRepositoryImpl>(() => ChickenRepositoryImpl(dioRemote));
diChicken.registerLazySingleton<ChickenRepositoryImpl>(() => ChickenRepositoryImpl(dioRemote));
diChicken.registerSingleton(ImagePicker());
}

View File

@@ -24,7 +24,7 @@ import 'package:rasadyar_core/core.dart';
import '../models/request/create_steward_free_bar/create_steward_free_bar.dart';
abstract class ChickenRepository {
Future<List<InventoryModel>?> getInventory({required String token});
Future<List<InventoryModel>?> getInventory({required String token, CancelToken? cancelToken});
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({required String token});
@@ -117,7 +117,7 @@ abstract class ChickenRepository {
required OutProvinceCarcassesBuyer body,
});
Future<List<IranProvinceCityModel>?> getProvince();
Future<List<IranProvinceCityModel>?> getProvince({CancelToken? cancelToken});
Future<List<IranProvinceCityModel>?> getCity({required String provinceName});

View File

@@ -30,10 +30,13 @@ class ChickenRepositoryImpl implements ChickenRepository {
ChickenRepositoryImpl(this._httpClient);
@override
Future<List<InventoryModel>?> getInventory({required String token}) async {
Future<List<InventoryModel>?> getInventory({required String token, CancelToken? cancelToken}) async {
eLog(_httpClient.baseUrl);
var res = await _httpClient.get(
'/roles-products/?role=Steward',
headers: {'Authorization': 'Bearer $token'},
fromJsonList: (json) =>
(json).map((item) => InventoryModel.fromJson(item as Map<String, dynamic>)).toList(),
);
@@ -290,7 +293,7 @@ class ChickenRepositoryImpl implements ChickenRepository {
}
@override
Future<List<IranProvinceCityModel>?> getProvince() async {
Future<List<IranProvinceCityModel>?> getProvince({CancelToken? cancelToken}) async {
var res = await _httpClient.get(
'/iran_province/',
fromJsonList: (json) =>

View File

@@ -9,20 +9,19 @@ import 'package:rasadyar_core/core.dart';
class HomeLogic extends GetxController {
RootLogic rootLogic = Get.find<RootLogic>();
RxnInt totalWeightTodayBars = RxnInt();
Rxn<InventoryModel> inventoryModel = Rxn<InventoryModel>();
Rxn<KillHouseDistributionInfo> killHouseDistributionInfo = Rxn<KillHouseDistributionInfo>();
RxBool isExpanded = false.obs;
@override
void onInit() {
super.onInit();
void onReady() {
super.onReady();
getTodayBars();
getInventory();
getDistributionInformation();
}
Future<void> getTodayBars() async {
await safeCall<BarInformation?>(
call: () async => await rootLogic.chickenRepository.getGeneralBarInformation(
@@ -30,51 +29,22 @@ class HomeLogic extends GetxController {
queryParameters: buildQueryParams(fromDate: DateTime.now(), toDate: DateTime.now()),
),
onSuccess: (result) {
iLog(result);
if (result != null) {
totalWeightTodayBars.value = result.totalBarsWeight?.toInt();
}
},
onError: (error, stackTrace) {
switch (error.response?.statusCode) {
case 401:
errorHandler(error);
break;
case 403:
errorHandler(error);
break;
default:
errorHandler(error);
}
},
);
}
Future<void> getInventory() async {
await safeCall<List<InventoryModel>?>(
call: () async => await rootLogic.chickenRepository.getInventory(token: rootLogic.tokenService.accessToken.value!),
onSuccess: (result) {
if (result != null) {
inventoryModel.value = result.first;
}
},
onError: (error, stackTrace) {
switch (error.response?.statusCode) {
case 401:
errorHandler(error);
break;
case 403:
errorHandler(error);
break;
default:
errorHandler(error);
}
},
);
}
Future<void> getDistributionInformation() async {
await safeCall<KillHouseDistributionInfo?>(
call: () async => await rootLogic.chickenRepository.getKillHouseDistributionInfo(token: rootLogic.tokenService.accessToken.value!),
call: () async => await rootLogic.chickenRepository.getKillHouseDistributionInfo(
token: rootLogic.tokenService.accessToken.value!,
),
onSuccess: (result) {
if (result != null) {
killHouseDistributionInfo.value = result;
@@ -85,19 +55,5 @@ class HomeLogic extends GetxController {
}
void errorHandler(DioException error) {
handleGeneric(error, () {
rootLogic.tokenService.deleteTokens();
});
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {
super.onClose();
}
}

View File

@@ -309,7 +309,7 @@ class HomePage extends GetView<HomeLogic> {
),
],
);
}, controller.inventoryModel),
}, controller.rootLogic.inventoryModel),
);
}
@@ -345,7 +345,7 @@ class HomePage extends GetView<HomeLogic> {
],
),
);
}, controller.inventoryModel);
}, controller.rootLogic.inventoryModel);
}
Widget _todayShipmentWidget() {

View File

@@ -1,7 +1,10 @@
import 'dart:async';
import 'package:flutter/material.dart' show Colors;
import 'package:flutter/widgets.dart';
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
import 'package:rasadyar_auth/data/utils/safe_call.dart';
import 'package:rasadyar_chicken/data/di/chicken_di.dart';
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
import 'package:rasadyar_chicken/data/repositories/chicken_repository.dart';
@@ -39,19 +42,39 @@ class RootLogic extends GetxController {
Rxn<InventoryModel> inventoryModel = Rxn<InventoryModel>();
RxList<IranProvinceCityModel> provinces = <IranProvinceCityModel>[].obs;
// Cancel tokens for API calls
CancelToken? _inventoryCancelToken;
CancelToken? _provincesCancelToken;
@override
void onInit() {
super.onInit();
dioRemote = DioRemote(baseUrl: tokenService.baseurl.value);
dioRemote.init();
chickenRepository = ChickenRepositoryImpl(dioRemote);
getProvinces();
chickenRepository = diChicken.get<ChickenRepositoryImpl>();
getInventory();
//getKillHouseDistributionInfo();
}
@override
void onReady() {
super.onReady();
// Only call these methods if they haven't been called before
if (provinces.isEmpty) {
getProvinces();
}
if (inventoryModel.value == null) {
getInventory();
}
}
@override
void onClose() {
// Cancel any ongoing requests when controller is disposed
_inventoryCancelToken?.cancel();
_provincesCancelToken?.cancel();
super.onClose();
}
void toggleExpanded(int index) {
if (inventoryExpandedList.keys.contains(index)) {
inventoryExpandedList.remove(index);
@@ -61,24 +84,24 @@ class RootLogic extends GetxController {
}
Future<void> getInventory() async {
// Cancel previous request if still running
_inventoryCancelToken?.cancel();
_inventoryCancelToken = CancelToken();
await safeCall<List<InventoryModel>?>(
call: () async =>
await chickenRepository.getInventory(token: tokenService.accessToken.value!),
call: () async => await chickenRepository.getInventory(
token: tokenService.accessToken.value!,
cancelToken: _inventoryCancelToken,
),
onSuccess: (result) {
if (result != null) {
inventoryModel.value = result.first;
}
},
onError: (error, stackTrace) {
switch (error.response?.statusCode) {
case 401:
errorHandler(error);
break;
case 403:
errorHandler(error);
break;
default:
errorHandler(error);
if (error is DioException && error.type == DioExceptionType.cancel) {
// Request was cancelled, ignore the error
return;
}
},
);
@@ -95,20 +118,22 @@ class RootLogic extends GetxController {
}
Future<void> getProvinces() async {
// Cancel previous request if still running
_provincesCancelToken?.cancel();
_provincesCancelToken = CancelToken();
try {
final res = await chickenRepository.getProvince();
final res = await chickenRepository.getProvince(cancelToken: _provincesCancelToken);
if (res != null) {
provinces.clear();
provinces.value = res;
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) {
// Request was cancelled, ignore the error
return;
}
provinces.clear();
}
}
void errorHandler(DioException error) {
handleGeneric(error, () {
tokenService.deleteTokens();
});
}
}

View File

@@ -8,14 +8,12 @@ import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
import 'package:rasadyar_core/core.dart';
class SaleLogic extends GetxController {
Rxn<List<AllocatedMadeModel>?> allocatedMadeModel =
Rxn<List<AllocatedMadeModel>?>();
Rxn<List<AllocatedMadeModel>?> allocatedMadeModel = Rxn<List<AllocatedMadeModel>?>();
RxList<ProductModel> rolesProductsModel = RxList<ProductModel>();
RxList<GuildModel> guildsModel = <GuildModel>[].obs;
Rxn<StewardFreeBarDashboard> stewardFreeDashboard =
Rxn<StewardFreeBarDashboard>();
Rxn<StewardFreeBarDashboard> stewardFreeDashboard = Rxn<StewardFreeBarDashboard>();
RootLogic rootLogic = Get.find<RootLogic>();
@@ -25,6 +23,11 @@ class SaleLogic extends GetxController {
void onInit() {
super.onInit();
routesName = [...rootLogic.routesName, 'فروش'].toList();
}
@override
void onReady() {
super.onReady();
getStewardDashBord();
getRolesProducts();
}
@@ -33,12 +36,7 @@ class SaleLogic extends GetxController {
safeCall(
call: () async => await rootLogic.chickenRepository.getAllocatedMade(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
page: 1,
pageSize: 20,
search: 'filter',
role: 'Steward',
),
queryParameters: buildQueryParams(page: 1, pageSize: 20, search: 'filter', role: 'Steward'),
),
onSuccess: (result) {
if (result != null) {
@@ -81,8 +79,7 @@ class SaleLogic extends GetxController {
safeCall(
call: () async => await rootLogic.chickenRepository.confirmAllAllocation(
token: rootLogic.tokenService.accessToken.value!,
allocationTokens:
allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [],
allocationTokens: allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [],
),
onSuccess: (result) {
getAllocatedMade();

View File

@@ -1,11 +1,7 @@
import 'package:rasadyar_auth/auth.dart';
import 'package:rasadyar_chicken/presentation/pages/buy/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/buy/view.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province/view.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province_all/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province_waiting/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_out_of_province/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_out_of_province/view.dart';
import 'package:rasadyar_chicken/presentation/pages/home/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/home/view.dart';
@@ -14,18 +10,13 @@ import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/root/view.dart';
import 'package:rasadyar_chicken/presentation/pages/sale/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/sale/view.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_in_province/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_in_province/view.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/view.dart';
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
import 'package:rasadyar_core/core.dart';
import '../pages/sales_out_of_province_buyers/logic.dart';
import '../pages/sales_out_of_province_sales_list/logic.dart';
sealed class ChickenPages {
ChickenPages._();
@@ -35,12 +26,12 @@ sealed class ChickenPages {
page: () => RootPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.put(RootLogic());
Get.lazyPut(() => RootLogic());
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => HomeLogic());
Get.lazyPut(() => BuyLogic());
Get.lazyPut(() => SaleLogic());
Get.lazyPut(() => ProfileLogic());
Get.lazyPut(() => BaseLogic());
}),
),
@@ -50,8 +41,7 @@ sealed class ChickenPages {
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.put(HomeLogic());
Get.put(RootLogic());
Get.lazyPut(() => BaseLogic());
//Get.lazyPut(() => BaseLogic());
}),
),
@@ -61,7 +51,7 @@ sealed class ChickenPages {
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => EnteringTheWarehouseLogic());
Get.lazyPut(() => RootLogic());
// RootLogic already registered in root page binding
}),
),*/
@@ -72,9 +62,9 @@ sealed class ChickenPages {
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => SaleLogic());
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SalesOutOfProvinceLogic());
Get.lazyPut(() => RootLogic());
//Get.lazyPut(() => BaseLogic());
//Get.lazyPut(() => SalesOutOfProvinceLogic());
//Get.lazyPut(() => RootLogic());
}),
),
GetPage(
@@ -82,13 +72,10 @@ sealed class ChickenPages {
page: () => SalesOutOfProvincePage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => RootLogic());
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SearchLogic());
Get.lazyPut(() => SalesOutOfProvinceLogic());
Get.lazyPut(() => SalesOutOfProvinceBuyersLogic());
Get.lazyPut(() => SalesOutOfProvinceSalesListLogic());
// Get.lazyPut(() => SalesOutOfProvinceLogic());
// Get.lazyPut(() => SalesOutOfProvinceBuyersLogic());
// Get.lazyPut(() => SalesOutOfProvinceSalesListLogic());
}),
),
GetPage(
@@ -97,8 +84,7 @@ sealed class ChickenPages {
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SalesInProvinceLogic());
Get.lazyPut(() => RootLogic());
// Get.lazyPut(() => SalesInProvinceLogic());
Get.lazyPut(() => SearchLogic());
}),
),
@@ -111,7 +97,6 @@ sealed class ChickenPages {
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => BuyLogic());
Get.lazyPut(() => RootLogic());
}),
),
@@ -122,8 +107,7 @@ sealed class ChickenPages {
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SearchLogic());
Get.lazyPut(() => BuyOutOfProvinceLogic());
Get.lazyPut(() => RootLogic());
// Get.lazyPut(() => BuyOutOfProvinceLogic());
}),
),
@@ -134,10 +118,9 @@ sealed class ChickenPages {
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SearchLogic());
Get.lazyPut(() => BuyInProvinceLogic());
Get.lazyPut(() => BuyInProvinceWaitingLogic());
Get.lazyPut(() => BuyInProvinceAllLogic());
Get.lazyPut(() => RootLogic());
// Get.lazyPut(() => BuyInProvinceLogic());
// Get.lazyPut(() => BuyInProvinceWaitingLogic());
// Get.lazyPut(() => BuyInProvinceAllLogic());
}),
),
];

View File

@@ -1,8 +1,8 @@
sealed class ChickenRoutes {
ChickenRoutes._();
static const _base = '/init';
static const init = '$_base/root';
static const _base = '/chicken';
static const init = '$_base/';
static const home = '$_base/home';
static const buy = '$_base/buy';
static const sale = '$_base/sale';