diff --git a/assets/images/login_logo.png b/assets/images/login_logo.png new file mode 100644 index 0000000..8c2e9d6 Binary files /dev/null and b/assets/images/login_logo.png differ diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/lib/config/env_config.dart b/lib/config/env_config.dart new file mode 100644 index 0000000..332cbe1 --- /dev/null +++ b/lib/config/env_config.dart @@ -0,0 +1,49 @@ +import 'package:flutter/foundation.dart'; + +/// 环境类型枚举 +enum Environment { dev, release } + +/// 环境配置管理类 +class EnvConfig { + // 当前环境 + static Environment current = Environment.dev; // 默认开发环境 + + // 开发环境配置 + static const Map _devConfig = { + 'mainBaseUrl': 'https://dating-agency-api-test.qniao.cn', + 'fileBaseUrl': 'https://dating-agency-api-test.qniao.cn', + }; + + // 生产环境配置 + static const Map _releaseConfig = { + 'mainBaseUrl': 'https://dating-agency-api-test.qniao.cn', + 'fileBaseUrl': 'https://dating-agency-api-test.qniao.cn', + }; + + /// 获取当前环境的配置值 + static String get(String key) { + return (current == Environment.dev + ? _devConfig[key] + : _releaseConfig[key]) ?? + ''; + } + + /// 获取主API的baseUrl + static String get mainBaseUrl { + return current == Environment.dev + ? _devConfig['mainBaseUrl']! + : _releaseConfig['mainBaseUrl']!; + } + + /// 获取文件API的baseUrl + static String get fileBaseUrl { + return current == Environment.dev + ? _devConfig['fileBaseUrl']! + : _releaseConfig['fileBaseUrl']!; + } + + /// 设置环境(主要用于测试或特定场景) + static void setEnvironment(Environment env) { + current = env; + } +} diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart new file mode 100644 index 0000000..f252c85 --- /dev/null +++ b/lib/generated/assets.dart @@ -0,0 +1,7 @@ +///This file is automatically generated. DO NOT EDIT, all your changes would be lost. +class Assets { + Assets._(); + + static const String imagesLoginLogo = 'assets/images/login_logo.png'; + +} diff --git a/lib/main.dart b/lib/main.dart index 7b7f5b6..cfecb75 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,122 +1,71 @@ +import 'dart:io'; + +import 'package:dating_touchme_app/config/env_config.dart'; +import 'package:dating_touchme_app/pages/main_page.dart'; +import 'package:dating_touchme_app/pages/mine/login_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; -void main() { - runApp(const MyApp()); -} +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + // 初始化GetStorage + await GetStorage.init(); -class MyApp extends StatelessWidget { - const MyApp({super.key}); + // 设置环境配置 - 根据是否为release模式 + EnvConfig.setEnvironment(Environment.dev); - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a purple toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: Brightness.dark, + statusBarBrightness: Brightness.light, + systemNavigationBarColor: Colors.white, + systemNavigationBarIconBrightness: Brightness.dark, + ), + ); + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + + if (Platform.isIOS) { + SystemChrome.setEnabledSystemUIMode( + SystemUiMode.manual, + overlays: [SystemUiOverlay.top], ); } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); + runApp( + GetMaterialApp( + locale: Get.locale, // 使用GetX的locale + supportedLocales: const [Locale('zh', 'CN')], - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); + /// 国际化配置 代理 + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, // iOS + ], + builder: FlutterSmartDialog.init(), + home: MyApp(), + ), + ); } -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } +class MyApp extends StatelessWidget { + const MyApp({super.key}); + // This widget is the root of your application. @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); + ScreenUtil.init(context, designSize: const Size(375, 812)); + + // 判断token是否为空 + final storage = GetStorage(); + final token = storage.read('token'); + + // 如果token为空,显示登录页面,否则显示主页 + return token == null || token.isEmpty ? const LoginPage() : MainPage(); } } diff --git a/lib/network/api_service.dart b/lib/network/api_service.dart new file mode 100644 index 0000000..2206dc8 --- /dev/null +++ b/lib/network/api_service.dart @@ -0,0 +1,20 @@ +import 'package:retrofit/retrofit.dart'; +import 'package:dio/dio.dart'; + +part 'api_service.g.dart'; + +@RestApi(baseUrl: 'https://api.example.com/') +abstract class ApiService { + factory ApiService(Dio dio) = _ApiService; + + @GET("{path}") + Future> get( + @Path("path") String path, + ); + + @POST("{path}") + Future> post( + @Path("path") String path, + @Body() dynamic data, + ); +} \ No newline at end of file diff --git a/lib/network/api_service.g.dart b/lib/network/api_service.g.dart new file mode 100644 index 0000000..bfee117 --- /dev/null +++ b/lib/network/api_service.g.dart @@ -0,0 +1,96 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'api_service.dart'; + +// dart format off + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations,unused_element_parameter,avoid_unused_constructor_parameters,unreachable_from_main + +class _ApiService implements ApiService { + _ApiService(this._dio, {this.baseUrl, this.errorLogger}) { + baseUrl ??= 'https://api.example.com/'; + } + + final Dio _dio; + + String? baseUrl; + + final ParseErrorLogger? errorLogger; + + @override + Future> get(String path) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType>( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + '${path}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch(_options); + final _value = _result.data; + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + @override + Future> post(String path, dynamic data) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = data; + final _options = _setStreamType>( + Options(method: 'POST', headers: _headers, extra: _extra) + .compose( + _dio.options, + '${path}', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch(_options); + final _value = _result.data; + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} + +// dart format on diff --git a/lib/network/index.dart b/lib/network/index.dart new file mode 100644 index 0000000..cd5873c --- /dev/null +++ b/lib/network/index.dart @@ -0,0 +1,4 @@ +export 'api_service.dart'; +export 'network_config.dart'; +export 'network_service.dart'; +export 'response_model.dart'; \ No newline at end of file diff --git a/lib/network/network_config.dart b/lib/network/network_config.dart new file mode 100644 index 0000000..ba0ef7a --- /dev/null +++ b/lib/network/network_config.dart @@ -0,0 +1,169 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart' hide Response; +import 'package:get_storage/get_storage.dart'; + +import '../config/env_config.dart'; +import '../pages/mine/login_page.dart'; + +/// API类型枚举,用于区分不同的baseUrl +enum ApiType { + main, // 主API + file, // 文件上传下载API +} + +/// 网络请求配置类 +class NetworkConfig { + static const int connectTimeout = 30000; + static const int receiveTimeout = 30000; + + /// 根据API类型创建不同的Dio实例 + static Dio createDio({ApiType type = ApiType.main}) { + // 根据类型选择对应的baseUrl + String currentBaseUrl; + switch (type) { + case ApiType.main: + currentBaseUrl = EnvConfig.mainBaseUrl; + break; + case ApiType.file: + currentBaseUrl = EnvConfig.fileBaseUrl; + break; + } + + final dio = Dio( + BaseOptions( + baseUrl: currentBaseUrl, + connectTimeout: Duration(milliseconds: connectTimeout), + receiveTimeout: Duration(milliseconds: receiveTimeout), + contentType: 'application/json', + responseType: ResponseType.json, + ), + ); + + // 添加请求拦截器 + dio.interceptors.add(AuthInterceptor()); + + // 添加响应拦截器 + dio.interceptors.add(ResponseInterceptor()); + + // 添加日志拦截器 + dio.interceptors.add(LogInterceptor( + requestBody: true, + responseBody: true, + error: true, + )); + + return dio; + } +} + +/// 请求拦截器 +class AuthInterceptor extends Interceptor { + @override + void onRequest( + RequestOptions options, + RequestInterceptorHandler handler, + ) async { + // 添加token等认证信息 + final token = _getToken(); + if (token != null && token.isNotEmpty) { + options.headers['Authorization'] = 'Bearer $token'; + } + + // 添加其他通用请求头 + options.headers['X-APP-ID'] = ''; + + handler.next(options); + } + + String? _getToken() { + // 从本地存储获取token + // 这里可以使用get_storage或其他存储方式 + return GetStorage().read('token'); + } +} + +/// 响应拦截器 +class ResponseInterceptor extends Interceptor { + @override + void onResponse( + Response response, + ResponseInterceptorHandler handler, + ) { + // 统一处理响应数据 + final data = response.data; + + // 检查响应状态码 + if (response.statusCode == 200) { + // 假设后端返回的数据格式为 {"code": 0, "message": "success", "data": {...}} + if (data is Map) { + final code = data['code'] ?? 0; + if (code == 0) { + // 请求成功 + handler.next(response); + } else { + // 业务错误 + final message = data['message'] ?? '请求失败'; + _showError(message); + handler.reject(DioException( + requestOptions: response.requestOptions, + error: message, + type: DioExceptionType.badResponse, + )); + } + } else { + handler.next(response); + } + } else { + handler.next(response); + } + } + + @override + void onError(DioException err, ErrorInterceptorHandler handler) { + // 统一处理错误 + String errorMessage = '网络请求失败'; + + switch (err.type) { + case DioExceptionType.connectionTimeout: + case DioExceptionType.sendTimeout: + case DioExceptionType.receiveTimeout: + errorMessage = '网络连接超时,请检查网络'; + break; + case DioExceptionType.badResponse: + if (err.response?.statusCode == 401) { + errorMessage = '登录已过期,请重新登录'; + _handleTokenExpired(); + } else if (err.response?.statusCode == 403) { + errorMessage = '没有权限访问该资源'; + } else if (err.response?.statusCode == 404) { + errorMessage = '请求的资源不存在'; + } else if (err.response?.statusCode == 500) { + errorMessage = '服务器内部错误'; + } else { + errorMessage = '请求失败,状态码:${err.response?.statusCode}'; + } + break; + case DioExceptionType.cancel: + errorMessage = '请求已取消'; + break; + default: + errorMessage = err.message ?? '未知错误'; + } + + _showError(errorMessage); + handler.reject(err); + } + + void _showError(String message) { + // 使用FlutterSmartDialog显示错误信息 + SmartDialog.showToast(message, displayTime: const Duration(seconds: 2)); + } + + void _handleTokenExpired() { + // 处理token过期逻辑,如清除本地数据、跳转登录页等 + // 这里可以使用Get.offAllNamed('/login')等方式跳转 + GetStorage().remove('token'); + Get.offAll(() => LoginPage()); + } +} \ No newline at end of file diff --git a/lib/network/network_service.dart b/lib/network/network_service.dart new file mode 100644 index 0000000..59264b2 --- /dev/null +++ b/lib/network/network_service.dart @@ -0,0 +1,189 @@ +import 'package:dio/dio.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:retrofit/retrofit.dart'; + +import 'api_service.dart'; +import 'network_config.dart'; +import 'user_api.dart'; + +/// 网络请求服务管理器 +class NetworkService { + static final NetworkService _instance = NetworkService._internal(); + + // API服务实例 + late final ApiService _apiService; // 主API服务 + late final ApiService _fileApiService; // 文件API服务 + late final UserApi _userApi; + + /// 获取单例实例 + factory NetworkService() { + return _instance; + } + + NetworkService._internal() { + // 初始化API服务 - 使用主API + final dio = NetworkConfig.createDio(); + _apiService = ApiService(dio); + _userApi = UserApi(dio); + + // 初始化文件上传API服务 + final fileDio = NetworkConfig.createDio(type: ApiType.file); + _fileApiService = ApiService(fileDio); + + + } + + /// 通用GET请求 + Future get( + String path, + {Map? queryParameters, + bool showLoading = false, + bool showError = true, + ApiType apiType = ApiType.main}) async { + try { + if (showLoading) { + _showLoading(); + } + + // 如果有queryParameters,将其附加到path + String finalPath = path; + if (queryParameters != null && queryParameters.isNotEmpty) { + final queryString = queryParameters.entries + .map((e) => '${e.key}=${e.value}') + .join('&'); + finalPath = '$path?$queryString'; + } + + // 根据API类型选择对应的服务 + final apiService = _getApiServiceByType(apiType); + final response = await apiService.get(finalPath); + + return response.data; + } catch (e) { + if (showError) { + _handleError(e); + } + return null; + } finally { + if (showLoading) { + _hideLoading(); + } + } + } + + /// 通用POST请求 + Future post( + String path, + dynamic data, + {bool showLoading = false, + bool showError = true, + ApiType apiType = ApiType.main}) async { + try { + if (showLoading) { + _showLoading(); + } + + // 根据API类型选择对应的服务 + final apiService = _getApiServiceByType(apiType); + final response = await apiService.post( + path, + data, + ); + + return response.data; + } catch (e) { + if (showError) { + _handleError(e); + } + return null; + } finally { + if (showLoading) { + _hideLoading(); + } + } + } + + /// 通用PUT请求(通过POST模拟) + Future put( + String path, + dynamic data, + {bool showLoading = false, + bool showError = true, + ApiType apiType = ApiType.main}) async { + // 注意:这是一个简化实现,实际项目中应该使用真实的PUT方法 + try { + if (showLoading) { + _showLoading(); + } + + // 在实际项目中,应该使用支持PUT方法的API服务 + // 这里使用POST作为替代 + final apiService = _getApiServiceByType(apiType); + final response = await apiService.post( + path, + data, + ); + + return response.data; + } catch (e) { + if (showError) { + _handleError(e); + } + return null; + } finally { + if (showLoading) { + _hideLoading(); + } + } + } + + /// 通用DELETE请求(通过GET模拟) + Future delete( + String path, + {bool showLoading = false, + bool showError = true, + ApiType apiType = ApiType.main}) async { + // 注意:这是一个简化实现,实际项目中应该使用真实的DELETE方法 + return get(path, showLoading: showLoading, showError: showError, apiType: apiType); + } + + /// 通用PATCH请求(通过POST模拟) + Future patch( + String path, + dynamic data, + {bool showLoading = false, + bool showError = true, + ApiType apiType = ApiType.main}) async { + // 注意:这是一个简化实现,实际项目中应该使用真实的PATCH方法 + return post(path, data, showLoading: showLoading, showError: showError, apiType: apiType); + } + + /// 根据API类型获取对应的API服务实例 + ApiService _getApiServiceByType(ApiType type) { + switch (type) { + case ApiType.main: + return _apiService; + case ApiType.file: + return _fileApiService; + } + } + + /// 用户相关API + UserApi get userApi => _userApi; + + void _showLoading() { + // 使用FlutterSmartDialog显示加载指示器 + SmartDialog.showLoading(); + } + + void _hideLoading() { + // 隐藏加载指示器 + SmartDialog.dismiss(); + } + + void _handleError(dynamic error) { + // 统一错误处理逻辑 + print('网络错误: $error'); + // 这里可以根据不同的错误类型进行处理 + } +} \ No newline at end of file diff --git a/lib/network/response_model.dart b/lib/network/response_model.dart new file mode 100644 index 0000000..43cfe1f --- /dev/null +++ b/lib/network/response_model.dart @@ -0,0 +1,92 @@ +/// API响应模型基类 +class BaseResponse { + final int code; + final String message; + final T? data; + + BaseResponse({ + required this.code, + required this.message, + this.data, + }); + + factory BaseResponse.fromJson(Map json, T Function(dynamic)? fromJsonT) { + return BaseResponse( + code: json['code'] ?? 0, + message: json['message'] ?? '', + data: fromJsonT != null && json.containsKey('data') && json['data'] != null + ? fromJsonT(json['data']) + : null, + ); + } + + Map toJson(Object? Function(T?)? toJsonT) { + final Map data = {}; + data['code'] = code; + data['message'] = message; + if (this.data != null && toJsonT != null) { + data['data'] = toJsonT(this.data); + } + return data; + } + + /// 是否请求成功 + bool get isSuccess => code == 0; + + @override + String toString() { + return 'BaseResponse{code: $code, message: $message, data: $data}'; + } +} + +/// 分页响应模型 +class PaginatedResponse { + final List list; + final int total; + final int page; + final int pageSize; + final bool hasMore; + + PaginatedResponse({ + required this.list, + required this.total, + required this.page, + required this.pageSize, + this.hasMore = false, + }); + + factory PaginatedResponse.fromJson( + Map json, + T Function(dynamic) fromJsonT, + ) { + final list = []; + if (json['list'] != null && json['list'] is List) { + for (final item in json['list']) { + list.add(fromJsonT(item)); + } + } + + return PaginatedResponse( + list: list, + total: json['total'] ?? 0, + page: json['page'] ?? 1, + pageSize: json['pageSize'] ?? 10, + hasMore: json['hasMore'] ?? false, + ); + } + + Map toJson(Object Function(T) toJsonT) { + return { + 'list': list.map((e) => toJsonT(e)).toList(), + 'total': total, + 'page': page, + 'pageSize': pageSize, + 'hasMore': hasMore, + }; + } + + @override + String toString() { + return 'PaginatedResponse{list: $list, total: $total, page: $page, pageSize: $pageSize, hasMore: $hasMore}'; + } +} \ No newline at end of file diff --git a/lib/network/user_api.dart b/lib/network/user_api.dart new file mode 100644 index 0000000..10be5c8 --- /dev/null +++ b/lib/network/user_api.dart @@ -0,0 +1,17 @@ +import 'package:retrofit/retrofit.dart'; +import 'package:dio/dio.dart'; + +part 'user_api.g.dart'; + +@RestApi(baseUrl: 'https://api.example.com/') +abstract class UserApi { + factory UserApi(Dio dio) = _UserApi; + + @POST("auth/login") + Future> login( + @Body() Map data, + ); + + @GET("user/info") + Future> getUserInfo(); +} \ No newline at end of file diff --git a/lib/network/user_api.g.dart b/lib/network/user_api.g.dart new file mode 100644 index 0000000..0889e19 --- /dev/null +++ b/lib/network/user_api.g.dart @@ -0,0 +1,97 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_api.dart'; + +// dart format off + +// ************************************************************************** +// RetrofitGenerator +// ************************************************************************** + +// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations,unused_element_parameter,avoid_unused_constructor_parameters,unreachable_from_main + +class _UserApi implements UserApi { + _UserApi(this._dio, {this.baseUrl, this.errorLogger}) { + baseUrl ??= 'https://api.example.com/'; + } + + final Dio _dio; + + String? baseUrl; + + final ParseErrorLogger? errorLogger; + + @override + Future> login(Map data) async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + final _data = {}; + _data.addAll(data); + final _options = _setStreamType>( + Options(method: 'POST', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'auth/login', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch(_options); + final _value = _result.data; + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + @override + Future> getUserInfo() async { + final _extra = {}; + final queryParameters = {}; + final _headers = {}; + const Map? _data = null; + final _options = _setStreamType>( + Options(method: 'GET', headers: _headers, extra: _extra) + .compose( + _dio.options, + 'user/info', + queryParameters: queryParameters, + data: _data, + ) + .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)), + ); + final _result = await _dio.fetch(_options); + final _value = _result.data; + final httpResponse = HttpResponse(_value, _result); + return httpResponse; + } + + RequestOptions _setStreamType(RequestOptions requestOptions) { + if (T != dynamic && + !(requestOptions.responseType == ResponseType.bytes || + requestOptions.responseType == ResponseType.stream)) { + if (T == String) { + requestOptions.responseType = ResponseType.plain; + } else { + requestOptions.responseType = ResponseType.json; + } + } + return requestOptions; + } + + String _combineBaseUrls(String dioBaseUrl, String? baseUrl) { + if (baseUrl == null || baseUrl.trim().isEmpty) { + return dioBaseUrl; + } + + final url = Uri.parse(baseUrl); + + if (url.isAbsolute) { + return url.toString(); + } + + return Uri.parse(dioBaseUrl).resolveUri(url).toString(); + } +} + +// dart format on diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart new file mode 100644 index 0000000..da31f52 --- /dev/null +++ b/lib/pages/main_page.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class MainPage extends StatefulWidget { + const MainPage({super.key}); + + @override + State createState() => _MainPageState(); +} + +class _MainPageState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/lib/pages/mine/login_page.dart b/lib/pages/mine/login_page.dart new file mode 100644 index 0000000..6087cae --- /dev/null +++ b/lib/pages/mine/login_page.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class LoginPage extends StatefulWidget { + const LoginPage({super.key}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} diff --git a/pubspec.lock b/pubspec.lock index 182dc93..d8c8d3e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,46 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: f0bb5d1648339c8308cc0b9838d8456b3cfe5c91f9dc1a735b4d003269e5da9a + url: "https://pub.flutter-io.cn" + source: hosted + version: "88.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "0b7b9c329d2879f8f05d6c05b32ee9ec025f39b077864bdb5ac9a7b63418a98f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "8.1.1" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.3" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.7.0" async: dependency: transitive description: @@ -17,6 +57,54 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: dfb67ccc9a78c642193e0c2d94cb9e48c2c818b3178a86097d644acdcde6a8d9 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.2" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "409002f1adeea601018715d613115cfaf0e31f512cb80ae4534c79867ae2363d" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.0" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: a9461b8e586bf018dd4afd2e13b49b08c6a844a4b226c8d1d10f3a723cdd78c3 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.10.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d + url: "https://pub.flutter-io.cn" + source: hosted + version: "8.12.0" characters: dependency: transitive description: @@ -25,6 +113,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.4" clock: dependency: transitive description: @@ -33,6 +129,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.11.0" collection: dependency: transitive description: @@ -41,6 +145,38 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.5" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.6" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.2" cupertino_icons: dependency: "direct main" description: @@ -49,6 +185,38 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.8" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: c87dfe3d56f183ffe9106a18aebc6db431fc7c98c31a54b952a77f3d54a85697 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.2" + dio: + dependency: "direct main" + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + event_bus: + dependency: "direct main" + description: + name: event_bus + sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.1" fake_async: dependency: transitive description: @@ -57,6 +225,62 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.9.3+2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "88707a3bec4b988aaed3b4df5d7441ee4e987f20b286cddca5d6a8270cab23f2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.9.4+5" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.9.3+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -70,11 +294,237 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_native_splash: + dependency: "direct main" + description: + name: flutter_native_splash + sha256: "4fb9f4113350d3a80841ce05ebf1976a36de622af7d19aca0ca9a9911c7ff002" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.7" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.32" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.9.3" + flutter_smart_dialog: + dependency: "direct main" + description: + name: flutter_smart_dialog + sha256: "0852df132cb03fd8fc5144eb404c31eb7eb50c22aecb1cc2504f2f598090d756" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.9.8+9" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + get: + dependency: "direct main" + description: + name: get + sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.7.2" + get_storage: + dependency: "direct main" + description: + name: get_storage + sha256: "39db1fffe779d0c22b3a744376e86febe4ade43bf65e06eab5af707dc84185a2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.2" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.3.0" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.15.6" + http: + dependency: transitive + description: + name: http + sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.5.4" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: ca2a3b04d34e76157e9ae680ef16014fb4c2d20484e78417eaed6139330056f6 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.8.13+7" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.0" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: e675c22790bcc24e9abd455deead2b7a88de4b79f7327a281812f14de1a56f58 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.8.13+1" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.2+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.11.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.9.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: "33a040668b31b320aafa4822b7b1e177e163fc3c1e835c6750319d4ab23aa6fe" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.11.1" leak_tracker: dependency: transitive description: @@ -99,6 +549,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.0.2" + lean_builder: + dependency: transitive + description: + name: lean_builder + sha256: ef5cd5f907157eb7aa87d1704504b5a6386d2cbff88a3c2b3344477bab323ee9 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.2" lints: dependency: transitive description: @@ -107,6 +565,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.0" matcher: dependency: transitive description: @@ -131,6 +597,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.0" path: dependency: transitive description: @@ -139,11 +621,171 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.9.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.20" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.flutter-io.cn" + source: hosted + version: "7.0.1" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.8" + pool: + dependency: transitive + description: + name: pool + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.2" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.0.3" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "826d6a306be26f29e5cd9faeb0c97aad5897270341dab6dbd7b8acd675937006" + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.0" + retrofit: + dependency: "direct main" + description: + name: retrofit + sha256: "7d78824afa6eeeaf6ac58220910ee7a97597b39e93360d4bda230b7c6df45089" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.9.0" + retrofit_generator: + dependency: "direct dev" + description: + name: retrofit_generator + sha256: "47998fb9f214935e4eb00741aebc636ffcb62cb8ae73b474ac88127ce2744428" + url: "https://pub.flutter-io.cn" + source: hosted + version: "10.1.2" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.0" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.0" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "9098ab86015c4f1d8af6486b547b11100e73b193e1899015033cb3e14ad20243" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.2" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.3.8" source_span: dependency: transitive description: @@ -168,6 +810,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" string_scanner: dependency: transitive description: @@ -192,6 +842,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.7.6" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.4.0" + universal_io: + dependency: transitive + description: + name: universal_io + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.2" vector_math: dependency: transitive description: @@ -208,6 +874,70 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "15.0.2" + watcher: + dependency: transitive + description: + name: watcher + sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.4" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.3" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.6.1" + xxh3: + dependency: transitive + description: + name: xxh3 + sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916" + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.3" sdks: dart: ">=3.9.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml index 894ef1b..a1ffd83 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,10 +30,23 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 + get: ^4.7.2 + flutter_smart_dialog: ^4.9.7+8 + flutter_screenutil: ^5.9.3 + intl: ^0.20.2 + get_storage: ^2.1.1 + image_picker: ^1.1.1 + path_provider: ^2.1.4 + event_bus: ^2.0.1 + dio: ^5.9.0 + retrofit: ^4.9.0 + flutter_native_splash: ^2.4.7 dev_dependencies: flutter_test: @@ -45,6 +58,9 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 + build_runner: ^2.4.11 + json_serializable: ^6.7.1 + retrofit_generator: ^10.0.6 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -58,11 +74,11 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg + assets: + - assets/images/ # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see + # An images asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images # For details regarding adding assets from package dependencies, see