chore: release client-v1.0.61
Deploy Client / build-client-web (push) Successful in 38s
Deploy Client / build-windows (push) Successful in 1m52s
Deploy Client / build-macos (push) Successful in 1m55s
Deploy Client / build-android (push) Successful in 1m0s
Deploy Client / build-ios (push) Successful in 2m47s
Deploy Client / release-deploy-client (push) Successful in 1m21s
Deploy Client / build-client-web (push) Successful in 38s
Deploy Client / build-windows (push) Successful in 1m52s
Deploy Client / build-macos (push) Successful in 1m55s
Deploy Client / build-android (push) Successful in 1m0s
Deploy Client / build-ios (push) Successful in 2m47s
Deploy Client / release-deploy-client (push) Successful in 1m21s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/config/app_config.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
|
||||
/// 每次从离线恢复到在线时自增。
|
||||
/// 数据 provider 通过 watch 此值实现网络恢复后自动刷新。
|
||||
@@ -44,27 +45,25 @@ class ConnectivityNotifier extends StateNotifier<bool> {
|
||||
// 独立轻量 Dio:无拦截器。连接预算用 Future.timeout 逐次控制,
|
||||
// 故 BaseOptions 超时放宽到 15s 作为兜底。
|
||||
final _dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(seconds: 15),
|
||||
connectTimeout: AppConstants.connectivityTimeout,
|
||||
receiveTimeout: AppConstants.connectivityTimeout,
|
||||
));
|
||||
|
||||
/// 每次尝试的超时预算,逐次拉长(越来越长)。
|
||||
static const _budgets = <Duration>[
|
||||
Duration(seconds: 4),
|
||||
Duration(seconds: 8),
|
||||
Duration(seconds: 12),
|
||||
];
|
||||
static const _budgets = AppConstants.connectivityBudgets;
|
||||
|
||||
/// 在线时:每 30 秒轻量检测一次(单次,不重试)
|
||||
/// 在线时:轻量检测一次(单次,不重试)
|
||||
void _startOnlineTimer() {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(seconds: 30), (_) => _check());
|
||||
_timer =
|
||||
Timer.periodic(AppConstants.connectivityOnlinePoll, (_) => _check());
|
||||
}
|
||||
|
||||
/// 离线时:每 1 分钟嗅探一次,降低频率节省资源
|
||||
/// 离线时:降低频率嗅探,节省资源
|
||||
void _startOfflineTimer() {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(minutes: 1), (_) => _check());
|
||||
_timer =
|
||||
Timer.periodic(AppConstants.connectivityOfflinePoll, (_) => _check());
|
||||
}
|
||||
|
||||
/// 立即触发一次检测(供外部调用,如 API 请求失败 / 启动时)。单次,不重试。
|
||||
@@ -92,14 +91,14 @@ class ConnectivityNotifier extends StateNotifier<bool> {
|
||||
|
||||
/// 连通性检测。[withRetry]=true 时按 [_budgets] 退避重试,间隔递增。
|
||||
Future<bool> _check({bool withRetry = false}) async {
|
||||
final budgets = withRetry ? _budgets : const [Duration(seconds: 4)];
|
||||
final budgets = withRetry ? _budgets : AppConstants.connectivitySingleBudget;
|
||||
var ok = false;
|
||||
for (var i = 0; i < budgets.length; i++) {
|
||||
ok = await _ping(budgets[i]);
|
||||
if (ok) break;
|
||||
// 最后一次失败后不再等待;中间失败按递增间隔退避(0.6s, 1.2s…)
|
||||
if (i < budgets.length - 1) {
|
||||
await Future.delayed(Duration(milliseconds: 600 * (i + 1)));
|
||||
await Future.delayed(AppConstants.connectivityRetryStep * (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/finance.dart';
|
||||
import '../repositories/finance_repository.dart';
|
||||
@@ -16,7 +17,7 @@ final financeListProvider =
|
||||
|
||||
class FinanceListNotifier extends AsyncNotifier<PageResult<FinanceRecord>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
String _type = '';
|
||||
String _month = '';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/inventory.dart';
|
||||
import '../repositories/inventory_repository.dart';
|
||||
@@ -17,7 +18,7 @@ final inventoryListProvider =
|
||||
|
||||
class InventoryListNotifier extends AsyncNotifier<PageResult<Inventory>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
int? _warehouseId;
|
||||
String _keyword = '';
|
||||
List<String> _series = [];
|
||||
@@ -106,7 +107,7 @@ final inventoryLogProvider =
|
||||
|
||||
class InventoryLogNotifier extends AsyncNotifier<PageResult<InventoryLog>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
PageResult<InventoryLog>? _cache;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/partner.dart';
|
||||
import '../repositories/partner_repository.dart';
|
||||
@@ -25,7 +26,7 @@ final customerListProvider =
|
||||
class PartnerListNotifier extends AsyncNotifier<PageResult<Partner>> {
|
||||
final String? type;
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
String _keyword = '';
|
||||
PageResult<Partner>? _cache;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/product.dart';
|
||||
import '../repositories/product_repository.dart';
|
||||
@@ -17,7 +18,7 @@ final productListProvider =
|
||||
|
||||
class ProductListNotifier extends AsyncNotifier<PageResult<Product>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
String _keyword = '';
|
||||
int? _categoryId;
|
||||
PageResult<Product>? _cache;
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import 'license_provider.dart';
|
||||
|
||||
/// 登录态心跳:已登录时每 30s 执行一次 **单个** POST /auth/ping:
|
||||
@@ -27,7 +28,7 @@ class SessionHeartbeat {
|
||||
|
||||
void start() {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(seconds: 30), (_) => _ping());
|
||||
_timer = Timer.periodic(AppConstants.heartbeatInterval, (_) => _ping());
|
||||
}
|
||||
|
||||
Future<void> _ping() async {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/stock_in.dart';
|
||||
import '../repositories/stock_in_repository.dart';
|
||||
@@ -18,7 +19,7 @@ final stockInListProvider =
|
||||
|
||||
class StockInListNotifier extends AsyncNotifier<PageResult<StockInOrder>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
String _status = '';
|
||||
String? _startDate;
|
||||
String? _endDate;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../core/api/api_client.dart';
|
||||
import '../core/auth/auth_state.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
import '../core/models/page_result.dart';
|
||||
import '../models/stock_out.dart';
|
||||
import '../repositories/stock_out_repository.dart';
|
||||
@@ -18,7 +19,7 @@ final stockOutListProvider =
|
||||
|
||||
class StockOutListNotifier extends AsyncNotifier<PageResult<StockOutOrder>> {
|
||||
int _page = 1;
|
||||
int _pageSize = 20;
|
||||
int _pageSize = AppConstants.defaultPageSize;
|
||||
String _status = '';
|
||||
String? _startDate;
|
||||
String? _endDate;
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../core/config/app_config.dart';
|
||||
import '../core/config/app_constants.dart';
|
||||
|
||||
// ── 数据模型 ────────────────────────────────────────────────
|
||||
class AppUpdateInfo {
|
||||
@@ -40,8 +41,8 @@ class UpdateNotifier extends AsyncNotifier<AppUpdateInfo?> {
|
||||
bool _dismissed = false; // 用户已手动关闭非强制更新提示
|
||||
|
||||
final _dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 5),
|
||||
receiveTimeout: const Duration(seconds: 5),
|
||||
connectTimeout: AppConstants.updateCheckTimeout,
|
||||
receiveTimeout: AppConstants.updateCheckTimeout,
|
||||
));
|
||||
|
||||
@override
|
||||
@@ -51,12 +52,12 @@ class UpdateNotifier extends AsyncNotifier<AppUpdateInfo?> {
|
||||
_dio.close(force: true);
|
||||
});
|
||||
|
||||
// 启动后 3 秒延迟首次检查(避免与登录请求竞争)
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
// 启动后延迟首次检查(避免与登录请求竞争)
|
||||
await Future.delayed(AppConstants.updateInitialDelay);
|
||||
final result = await _check();
|
||||
|
||||
// 每小时检查一次
|
||||
_timer = Timer.periodic(const Duration(hours: 1), (_) async {
|
||||
// 定期检查更新
|
||||
_timer = Timer.periodic(AppConstants.updatePollInterval, (_) async {
|
||||
_dismissed = false;
|
||||
final r = await _check();
|
||||
state = AsyncValue.data(r);
|
||||
|
||||
Reference in New Issue
Block a user