diff --git a/android/app/build.gradle b/android/app/build.gradle index fee774f..c497b2d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -58,11 +58,6 @@ android { // signingConfig signingConfigs.release // } } - lintOptions { - disable 'InvalidPackage' - checkReleaseBuilds false - abortOnError false - } } flutter { diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7c45efc..882a27b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,9 +30,9 @@ - - + + diff --git a/android/app/src/main/res/ic_launcher.png b/android/app/src/main/res/ic_launcher.png deleted file mode 100644 index 7325a57..0000000 Binary files a/android/app/src/main/res/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index ab4708f..db77bb4 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-ldpi/ic_launcher.png b/android/app/src/main/res/mipmap-ldpi/ic_launcher.png deleted file mode 100644 index 36a6abb..0000000 Binary files a/android/app/src/main/res/mipmap-ldpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index c36cfc6..17987b7 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index eb524ff..09d4391 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 4ee0905..d5f1c8d 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index b13fdb6..4d6372e 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/icons/sms.png b/assets/icons/sms.png deleted file mode 100644 index 617b2c6..0000000 Binary files a/assets/icons/sms.png and /dev/null differ diff --git a/lib/constants/api.dart b/lib/constants/api.dart new file mode 100644 index 0000000..4f06a4d --- /dev/null +++ b/lib/constants/api.dart @@ -0,0 +1,41 @@ +import 'environment/environment.dart'; + +class API { + static const tokenKey = 'Telephony-Manage-Token'; + + ///HOST + static String get host { + if (DevEV.instance.dev) { + return 'http://10.0.2.2:8088'; + } else { + return 'https://api.yunyunwenche.com'; + } + } + + static String get imageHost { + if (DevEV.instance.dev) { + return 'http://10.0.2.2:8088'; + } else { + return 'https://static.yunyunwenche.com'; + } + } + static const int networkTimeOut = 10000; + + static String get baseURL => '$host'; + + static _Manager manager = _Manager(); + static _Pay pay = _Pay(); +} +class _Manager { + String get login => '/manage/login'; + String get logout => '/manage/login/logout'; + String get captcha => '/manage/captcha'; + String get info => '/manage/user/info'; +} + +class _Pay { + String get wxpay => '/manage/pay/wxpay'; + String get alipay => '/manage/pay/alipay'; + String get wxCallback => '/callback/wxpay/notify'; + String get aliCallback => '/callback/alipay/notify'; +} \ No newline at end of file diff --git a/lib/environment/environment.dart b/lib/constants/environment/environment.dart similarity index 100% rename from lib/environment/environment.dart rename to lib/constants/environment/environment.dart diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index 06adb78..377f5e6 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -35,9 +35,6 @@ class $AssetsIconsGen { /// File path: assets/icons/privacy.png AssetGenImage get privacy => const AssetGenImage('assets/icons/privacy.png'); - /// File path: assets/icons/sms.png - AssetGenImage get sms => const AssetGenImage('assets/icons/sms.png'); - /// File path: assets/icons/switch1.png AssetGenImage get switch1 => const AssetGenImage('assets/icons/switch1.png'); diff --git a/lib/main.dart b/lib/main.dart index a213478..8cc681f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,16 +1,13 @@ -// import 'dart:async'; import 'package:bot_toast/bot_toast.dart'; -// import 'package:call_log/call_log.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get_navigation/src/root/get_material_app.dart'; -import 'package:power_logger/power_logger.dart'; -// import 'package:permission_handler/permission_handler.dart'; -// import 'package:project_telephony/permission.dart'; -// import 'package:project_telephony/ui/login/login_page.dart'; +import 'package:project_telephony/providers/user_provider.dart'; import 'package:project_telephony/ui/tab_navigator.dart'; +import 'package:project_telephony/utils/hive_store.dart'; +import 'package:provider/provider.dart'; // import 'package:telephony/telephony.dart'; @@ -20,14 +17,11 @@ import 'package:project_telephony/ui/tab_navigator.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - FlutterError.onError = (details) { - LoggerData.addData(details); - FlutterError.presentError(details); - }; // await initializeService(); - WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); - + // SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle( + // statusBarColor: Colors.transparent, //状态栏背景色 + // statusBarIconBrightness: Brightness.dark); //状态栏字体颜色 } // Future initializeService() async { @@ -105,8 +99,11 @@ class _MyAppState extends State { @override void initState() { super.initState(); - // PowerLogger.start(context, debug: true); final service = FlutterBackgroundService(); + Future.delayed(const Duration(milliseconds: 0), () async { + //Hive.initFlutter; + await HiveStore.init(); + }); // JPush jPush=JPush(); // jPush.setup( // appKey: "", @@ -152,32 +149,37 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { - return MediaQuery( - data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window), - child: ScreenUtilInit( - designSize: const Size(750, 1334), - builder: (context, child) { - return AnnotatedRegion( - value: const SystemUiOverlayStyle( - statusBarColor: Colors.transparent, //状态栏背景色 - statusBarIconBrightness: Brightness.dark), - child: GetMaterialApp( - // get.testmode=true, - debugShowCheckedModeBanner: false, - home: const TabNavigator(), - builder: (context, child) { - // ScreenUtil.setContext(context); - return MediaQuery( - //设置文字大小不随系统设置改变 - data: MediaQueryData.fromWindow( - WidgetsBinding.instance!.window) - .copyWith(textScaleFactor: 1.0), - child: BotToastInit().call(context, child), - ); - }, - navigatorObservers: [BotToastNavigatorObserver()], - )); - }, - )); + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => UserProvider()), + ], + child: MediaQuery( + data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window), + child: ScreenUtilInit( + designSize: const Size(750, 1334), + builder: (context, child) { + return AnnotatedRegion( + value: const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, //状态栏背景色 + statusBarIconBrightness: Brightness.dark), + child: GetMaterialApp( + // get.testmode=true, + debugShowCheckedModeBanner: false, + home: const TabNavigator(), + builder: (context, child) { + // ScreenUtil.setContext(context); + return MediaQuery( + //设置文字大小不随系统设置改变 + data: MediaQueryData.fromWindow( + WidgetsBinding.instance!.window) + .copyWith(textScaleFactor: 1.0), + child: BotToastInit().call(context, child), + ); + }, + navigatorObservers: [BotToastNavigatorObserver()], + )); + }, + )), + ); } } diff --git a/lib/model/login_info_model.dart b/lib/model/login_info_model.dart new file mode 100644 index 0000000..6e9b19a --- /dev/null +++ b/lib/model/login_info_model.dart @@ -0,0 +1,41 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'login_info_model.g.dart'; + + +@JsonSerializable() +class LoginInfo extends Equatable { + final String token; + final User user; + + factory LoginInfo.fromJson(Map json) => + _$LoginInfoFromJson(json); + + const LoginInfo({ + required this.token, + required this.user, + }); + + @override + List get props => [token, user]; +} + +@JsonSerializable() +class User extends Equatable { + final int id; + final String name; + + const User({ + required this.id, + required this.name, + }); + + factory User.fromJson(Map json) => _$UserFromJson(json); + + @override + List get props => + [ + id, + name, + ]; +} \ No newline at end of file diff --git a/lib/model/login_info_model.g.dart b/lib/model/login_info_model.g.dart new file mode 100644 index 0000000..28e9a74 --- /dev/null +++ b/lib/model/login_info_model.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_info_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LoginInfo _$LoginInfoFromJson(Map json) => LoginInfo( + token: json['token'] as String, + user: User.fromJson(json['user'] as Map), + ); + +Map _$LoginInfoToJson(LoginInfo instance) => { + 'token': instance.token, + 'user': instance.user, + }; + +User _$UserFromJson(Map json) => User( + id: json['id'] as int, + name: json['name'] as String, + ); + +Map _$UserToJson(User instance) => { + 'id': instance.id, + 'name': instance.name, + }; diff --git a/lib/model/network/api_client.dart b/lib/model/network/api_client.dart new file mode 100644 index 0000000..bc0472b --- /dev/null +++ b/lib/model/network/api_client.dart @@ -0,0 +1,107 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:platform/platform.dart'; + +import '../../constants/api.dart'; +import '../../utils/toast/cloud_toast.dart'; +import 'base_list_model.dart'; +import 'base_model.dart'; +import 'net_interceptor.dart'; + +final ApiClient apiClient = ApiClient(); + +class ApiClient { + late Dio _dio; + + Dio get dio => _dio; + + ApiClient() { + var headers = {}; + if (kIsWeb) { + headers = {'device-type': 'web'}; + } else { + headers = { + 'device-type': const LocalPlatform().operatingSystem.toLowerCase() + }; + } + + _dio = Dio() + ..options.baseUrl = API.baseURL + ..options.headers = headers + ..interceptors.add(NetworkInterceptor()); + } + + ///设置token + Dio setToken(String token) { + return _dio..options.headers[API.tokenKey] = token; + } + + ///清除token + Dio clearToken() { + return _dio + ..options.headers.removeWhere((key, value) => key == API.tokenKey); + } + + ///发送请求 + Future request( + String path, { + dynamic data, + bool showMessage = false, + }) async { + try { + var response = await _dio.post(path, data: data); + var baseModel = BaseModel.fromJson(response.data); + if (showMessage) CloudToast.show(baseModel.msg); + return baseModel; + } catch (e) { + if (e is DioError) { + return BaseModel.dioErr(e); + } + } + + return BaseModel.unknown(); + } + + ///请求列表 + Future requestList( + String path, { + dynamic data, + bool showMessage = false, + }) async { + var response = await _dio.post(path, data: data); + var baseModel = BaseListModel.fromJson(response.data); + if (showMessage) CloudToast.show(baseModel.msg); + return baseModel; + } + + // ///上传图片 + // Future uploadImage(File file) async { + // var response = await _dio.post( + // API.file.uploadImage, + // data: FormData.fromMap( + // {'image': await MultipartFile.fromFile(file.path)}, + // ), + // ); + // var model = BaseModel.fromJson(response.data); + // return model.data['path']; + // } + + // Future> uploadFiles( + // List files, + // ) async { + // List urls = []; + // if (files.isEmpty) { + // return []; + // } else { + // for (var item in files) { + // String path = await uploadImage(item); + // if (path.isNotEmpty) { + // urls.add(path); + // } + // } + // } + // return urls; + // } +} diff --git a/lib/model/network/base_list_model.dart b/lib/model/network/base_list_model.dart new file mode 100644 index 0000000..3cd1d68 --- /dev/null +++ b/lib/model/network/base_list_model.dart @@ -0,0 +1,51 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'base_list_model.g.dart'; + +@JsonSerializable() +class BaseListModel { + final int code; + final String msg; + final ListInnerModel? data; + + BaseListModel({ + required this.code, + required this.msg, + required this.data, + }); + + factory BaseListModel.fromJson(Map json) => + _$BaseListModelFromJson(json); + + List get nullSafetyList { + if (data == null) { + return []; + } else if (data!.list == null) { + return []; + } else { + return data!.list!; + } + } + + int get nullSafetyTotal { + if (data == null) { + return 0; + } else { + return data!.total; + } + } +} + +@JsonSerializable() +class ListInnerModel { + final List? list; + final int total; + + ListInnerModel({ + this.list, + required this.total, + }); + + factory ListInnerModel.fromJson(Map json) => + _$ListInnerModelFromJson(json); +} diff --git a/lib/model/network/base_list_model.g.dart b/lib/model/network/base_list_model.g.dart new file mode 100644 index 0000000..bc5b729 --- /dev/null +++ b/lib/model/network/base_list_model.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'base_list_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +BaseListModel _$BaseListModelFromJson(Map json) => + BaseListModel( + code: json['code'] as int, + msg: json['msg'] as String, + data: json['data'] == null + ? null + : ListInnerModel.fromJson(json['data'] as Map), + ); + +Map _$BaseListModelToJson(BaseListModel instance) => + { + 'code': instance.code, + 'msg': instance.msg, + 'data': instance.data, + }; + +ListInnerModel _$ListInnerModelFromJson(Map json) => + ListInnerModel( + list: json['list'] as List?, + total: json['total'] as int, + ); + +Map _$ListInnerModelToJson(ListInnerModel instance) => + { + 'list': instance.list, + 'total': instance.total, + }; diff --git a/lib/model/network/base_model.dart b/lib/model/network/base_model.dart new file mode 100644 index 0000000..68cc933 --- /dev/null +++ b/lib/model/network/base_model.dart @@ -0,0 +1,36 @@ +import 'package:dio/dio.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'base_model.g.dart'; + +@JsonSerializable() +class BaseModel { + int code; + String msg; + dynamic data; + BaseModel({ + required this.code, + required this.msg, + this.data, + }); + + + + List map(T Function(dynamic json) f) { + if (data == null) return []; + return (data! as List).map(f).toList(); + } + + factory BaseModel.unknown() => BaseModel( + code: -1, + msg: 'UNKNOW FAIL', + ); + + factory BaseModel.dioErr(DioError err) => BaseModel( + code: err.response?.statusCode ?? -1, + msg: err.message, + ); + + factory BaseModel.fromJson(Map json) => + _$BaseModelFromJson(json) as BaseModel; +} diff --git a/lib/model/network/base_model.g.dart b/lib/model/network/base_model.g.dart new file mode 100644 index 0000000..aa90837 --- /dev/null +++ b/lib/model/network/base_model.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'base_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +BaseModel _$BaseModelFromJson(Map json) => BaseModel( + code: json['code'] as int, + msg: json['msg'] as String, + data: json['data'], + ); + +Map _$BaseModelToJson(BaseModel instance) => + { + 'code': instance.code, + 'msg': instance.msg, + 'data': instance.data, + }; diff --git a/lib/model/network/login_model.dart b/lib/model/network/login_model.dart new file mode 100644 index 0000000..b22b255 --- /dev/null +++ b/lib/model/network/login_model.dart @@ -0,0 +1,21 @@ +class LoginModel { + String? message; + String? token; + bool? status; + + LoginModel({this.message, this.token, this.status}); + + LoginModel.fromJson(Map json) { + message = json['message']; + token = json['token']; + status = json['status']; + } + + Map toJson() { + final Map data = new Map(); + data['message'] = this.message; + data['token'] = this.token; + data['status'] = this.status; + return data; + } +} diff --git a/lib/model/network/net_interceptor.dart b/lib/model/network/net_interceptor.dart new file mode 100644 index 0000000..2d77fcb --- /dev/null +++ b/lib/model/network/net_interceptor.dart @@ -0,0 +1,48 @@ +import 'package:dio/dio.dart'; +import 'package:get/get.dart' hide Response; +import 'package:power_logger/power_logger.dart'; +import 'package:provider/provider.dart'; +import '../../providers/user_provider.dart'; +import '../../ui/login/login_page.dart'; +import '../../utils/toast/cloud_toast.dart'; + +class NetworkInterceptor extends Interceptor { + @override + void onResponse(Response response, ResponseInterceptorHandler handler) async { + final userProvider = Provider.of(Get.context!, listen: false); + LoggerData.addData(response); + int code = response.data['code'] ?? 0; + switch (code) { + //登录超时 + case 100000: + await userProvider.logout(); + CloudToast.show(response.data['msg']); + await Get.offAll(() => const LoginPage()); + break; + default: + break; + } + super.onResponse(response, handler); + } + + @override + void onError(DioError err, ErrorInterceptorHandler handler) async { + LoggerData.addData(err); + switch (err.type) { + case DioErrorType.connectTimeout: + case DioErrorType.sendTimeout: + case DioErrorType.receiveTimeout: + CloudToast.show('连接超时'); + break; + case DioErrorType.response: + CloudToast.show('Server Err'); + break; + case DioErrorType.cancel: + break; + case DioErrorType.other: + CloudToast.show('网络出现问题'); + break; + } + super.onError(err, handler); + } +} diff --git a/lib/model/user_info_model.dart b/lib/model/user_info_model.dart new file mode 100644 index 0000000..99cbd71 --- /dev/null +++ b/lib/model/user_info_model.dart @@ -0,0 +1,55 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:equatable/equatable.dart'; + +part 'user_info_model.g.dart'; + +@JsonSerializable() +class UserInfoModel extends Equatable { + final int id; + final String name; + final String phone; + final int status; + final Vip vip; + + factory UserInfoModel.fromJson(Map json) => + _$UserInfoModelFromJson(json); + + Map toJson() => _$UserInfoModelToJson(this); + + static UserInfoModel get fail => const UserInfoModel( + id: 0, + name: '', + phone: '', + status: 0, + vip: Vip(start: '', end: ''), + ); + + @override + List get props => [id, name, phone, status, vip]; + + const UserInfoModel({ + required this.id, + required this.name, + required this.phone, + required this.status, + required this.vip, + }); +} + +@JsonSerializable() +class Vip extends Equatable { + final String start; + final String end; + + const Vip({ + required this.start, + required this.end, + }); + + factory Vip.fromJson(Map json) => _$VipFromJson(json); + + Map toJson() => _$VipToJson(this); + + @override + List get props => [start, end]; +} diff --git a/lib/model/user_info_model.g.dart b/lib/model/user_info_model.g.dart new file mode 100644 index 0000000..a2431ec --- /dev/null +++ b/lib/model/user_info_model.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_info_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserInfoModel _$UserInfoModelFromJson(Map json) => + UserInfoModel( + id: json['id'] as int, + name: json['name'] as String, + phone: json['phone'] as String, + status: json['status'] as int, + vip: Vip.fromJson(json['vip'] as Map), + ); + +Map _$UserInfoModelToJson(UserInfoModel instance) => + { + 'id': instance.id, + 'name': instance.name, + 'phone': instance.phone, + 'status': instance.status, + 'vip': instance.vip, + }; + +Vip _$VipFromJson(Map json) => Vip( + start: json['start'] as String, + end: json['end'] as String, + ); + +Map _$VipToJson(Vip instance) => { + 'start': instance.start, + 'end': instance.end, + }; diff --git a/lib/providers/user_provider.dart b/lib/providers/user_provider.dart new file mode 100644 index 0000000..e4c63dc --- /dev/null +++ b/lib/providers/user_provider.dart @@ -0,0 +1,56 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import '../constants/api.dart'; +import '../model/login_info_model.dart'; +import '../model/network/api_client.dart'; +import '../model/user_info_model.dart'; +import '../utils/hive_store.dart'; +import '../utils/toast/cloud_toast.dart'; + +class UserProvider extends ChangeNotifier { + bool _isLogin = false; + + bool get isLogin => _isLogin; + late UserInfoModel _userInfo; + + UserInfoModel get userInfo => _userInfo; + + Future init() async { + if (HiveStore.appBox?.containsKey('token') ?? false) { + final token = HiveStore.appBox?.get('token') as String; + _isLogin = true; + apiClient.setToken(token); + await updateUserInfo(); + return true; + } else { + _isLogin = false; + return false; + } + } + + Future setToken(String token, {User? user}) async { + apiClient.setToken(token); + await HiveStore.appBox!.put('token', token); + _isLogin = true; + //每次打开app更新用户信息 + await updateUserInfo(); + } + + Future logout() async { + apiClient.clearToken(); + _isLogin = false; + await HiveStore.appBox?.delete('token'); + } + + Future updateUserInfo() async { + var base = await apiClient.request(API.manager.info); + if (base.code == 0) { + _userInfo = UserInfoModel.fromJson(base.data); + } else { + CloudToast.show(base.msg); + _userInfo = UserInfoModel.fail; + } + notifyListeners(); + } +} diff --git a/lib/ui/home/content_page.dart b/lib/ui/home/content_page.dart index 339ea56..40c025e 100644 --- a/lib/ui/home/content_page.dart +++ b/lib/ui/home/content_page.dart @@ -1,18 +1,10 @@ -// import 'dart:async'; -// import android.app.PendingIntent; -// import android.telephony.SmsManager; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:project_telephony/base/base_style.dart'; import 'package:project_telephony/ui/home/content_details_page.dart'; import 'package:project_telephony/ui/widget/centertipsalterwidget.dart'; import 'package:project_telephony/ui/widget/plone_back_button.dart'; import 'package:project_telephony/utils/headers.dart'; -import 'package:telephony/telephony.dart'; - -import '../user/privacy_rights_page.dart'; class ContentPage extends StatefulWidget { final bool? isAnswer; //true接听false未接听 @@ -23,17 +15,6 @@ class ContentPage extends StatefulWidget { } class _ContentPageState extends State { - // static const platform=const MethodChannel("sendSms"); - // Future sendSms( String text) async{ - // print("sendSMS"); - // try{ - // final String result=await platform.invokeMethod('send', {"phone":"+8613486828191","msg":text}); - // print(result); - // } on PlatformException catch(e){ - // print(e.toString()); - // } - // } - // SmsManager smsManager = SmsManager.getDefault(); int _select = 0; List textList = ['欢迎你的来电', '祝您生活愉快', '感谢您的来电我们会尽快处理的', '自定义短信内容']; List textList1 = ['自定义短信内容']; @@ -79,33 +60,15 @@ class _ContentPageState extends State { textList.setAll(index, {textContent}); }, )); - } else { - bool? permissionsGranted = await telephony.requestPhonePermissions; - // print(permissionsGranted); - // if(permissionsGranted!){ - // print(content); - // // sendSms(content); - // telephony.sendSms( - // to: "13395740386", - // message: content, - // ); - // }else{ - // print(content); - // } - print(content); - // sendSms(content); - telephony.sendSms( - to: "13486828191", - message: content, - ); - } + } else {} setState(() {}); // print("这是数据" + textList[_s lect]); // print(index); }, onLongPress: () { - if (index != textList.length - 1) { + setState(() {}); + if (index == textList.length - 1) { showDialog( context: context, builder: (context) { @@ -115,7 +78,6 @@ class _ContentPageState extends State { ); }); } - setState(() {}); }, child: Container( // width: 686.w, diff --git a/lib/ui/home/home_page.dart b/lib/ui/home/home_page.dart index ff8397b..6e8945d 100644 --- a/lib/ui/home/home_page.dart +++ b/lib/ui/home/home_page.dart @@ -11,7 +11,6 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { @override - Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, @@ -20,11 +19,12 @@ class _HomePageState extends State { body: SafeArea( child: Column( children: [ - Image.asset( + Container( + child: Image.asset( Assets.images.homeBg.path, height: 722.w, width: 722.w, - ), + )), _getBody(), ], ), diff --git a/lib/ui/login/login_page.dart b/lib/ui/login/login_page.dart index 0d8bc14..e532155 100644 --- a/lib/ui/login/login_page.dart +++ b/lib/ui/login/login_page.dart @@ -8,8 +8,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:project_telephony/ui/widget/plone_back_button.dart'; import 'package:project_telephony/utils/headers.dart'; - +import 'package:provider/provider.dart'; import '../../base/base_style.dart'; +import '../../constants/api.dart'; +import '../../constants/environment/environment.dart'; +import '../../model/network/api_client.dart'; +import '../../providers/user_provider.dart'; +import '../../utils/toast/cloud_toast.dart'; +import '../../utils/user_tool.dart'; import '../tab_navigator.dart'; import '../widget/image_scaffold.dart'; import '../widget/plone_bottom.dart'; @@ -22,8 +28,6 @@ class LoginPage extends StatefulWidget { } class _LoginPageState extends State { - // String _operator=""; - // String _phone=""; bool _chooseAgreement = false; bool _getCodeEnable = true; late Timer _timer; @@ -33,24 +37,39 @@ class _LoginPageState extends State { ///初始化文本 int _countDownNum = 59; - - ///时间倒计数值 - // late final TextEditingController _phoneController = - // TextEditingController(text: ""); - // late final TextEditingController _smsCodeController = - // TextEditingController(text: ""); - - // late FocusNode _smsCodeFocusNode=FocusNode (canRequestFocus: ); + late TextEditingController _phoneController; + late TextEditingController _smsCodeController; + late FocusNode _phoneFocusNode; + late FocusNode _smsCodeFocusNode; bool _cantSelected = false; + @override void initState() { super.initState(); - // _operator = '中国移动认证'; - // _phone = '12345678909'; + _phoneFocusNode = FocusNode(); + _smsCodeFocusNode = FocusNode(); + _phoneController = TextEditingController(); + _smsCodeController = TextEditingController(); + final userProvider = Provider.of(context, listen: false); + var env = const String.fromEnvironment('ENV', defaultValue: 'dev'); + if (kDebugMode) { + print('env :$env'); + } + DevEV.instance.setEnvironment( + context, + environment: env == 'dev', + ); + } + + @override + void dispose() { + _phoneFocusNode.dispose(); + _smsCodeFocusNode.dispose(); + _phoneController.dispose(); + _smsCodeController.dispose(); + super.dispose(); } - String ploneText = ""; //手机号 - String codeText = ""; //验证码 @override Widget build(BuildContext context) { return CloudScaffold( @@ -99,20 +118,23 @@ class _LoginPageState extends State { 112.hb, PloneBottom( blM: false, - border: ploneText.length != 11, - opacity: ploneText.length == 11 ? 1 : 0.4, - onTap: () { - if (ploneText.length < 11) { + border: _phoneController.text.length != 11, + opacity: _phoneController.text.length == 11 ? 1 : 0.4, + onTap: () async{ + if (_phoneController.text.length < 11) { BotToast.showText(text: "请输入手机号"); - } else { - if (codeText.length < 6) { - BotToast.showText(text: "请输入验证码"); + }else if(_smsCodeController.text.length < 6){ + BotToast.showText(text: "请输入验证码"); + }else if(!_chooseAgreement){ + BotToast.showText(text: "请同意并勾选隐私政策"); + }else{ + var base = await apiClient.request(API.manager.login, + data: {'phone': _phoneController.text, 'code': _smsCodeController.text}); + if (base.code == 0) { + await UserTool.userProvider.setToken(base.data['token']); + Get.back(); } else { - if (_chooseAgreement) { - Get.to(() => const TabNavigator()); - } else { - BotToast.showText(text: "请同意并勾选隐私政策"); - } + CloudToast.show(base.msg); } } }, @@ -171,7 +193,7 @@ class _LoginPageState extends State { inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))], textCapitalization: TextCapitalization.none, onChanged: (text) { - ploneText = text; + _phoneController.text = text; setState(() {}); }, decoration: InputDecoration( @@ -186,9 +208,9 @@ class _LoginPageState extends State { onTap: !_getCodeEnable ? () {} : () async { - // await apiClient.request(API.login.phoneCode, data: { - // 'phone': UserTool.userProvider.userInfo.phone, - // }); + await apiClient.request(API.manager.captcha, data: { + 'phone': _phoneController.text, + }); _beginCountDown(); if (_cantSelected) return; _cantSelected = true; @@ -225,7 +247,7 @@ class _LoginPageState extends State { inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))], textCapitalization: TextCapitalization.none, onChanged: (text) { - codeText = text; + _smsCodeController.text = text; setState(() {}); }, decoration: InputDecoration( @@ -235,7 +257,7 @@ class _LoginPageState extends State { //textfield占位语,类似于iOS中的placeholder hintText: "请输入验证码", //占位语颜色 - hintStyle: TextStyle(color: Colors.black12), + hintStyle: const TextStyle(color: Colors.black12), ), ), ); diff --git a/lib/ui/user/privacy_rights_page.dart b/lib/ui/user/privacy_rights_page.dart index b4be750..cceb690 100644 --- a/lib/ui/user/privacy_rights_page.dart +++ b/lib/ui/user/privacy_rights_page.dart @@ -15,7 +15,6 @@ class PrivacyRightsPage extends StatefulWidget { } final Telephony telephony = Telephony.instance; - // late final bool permissionsGranted; // String body = ""; // @override @@ -93,9 +92,9 @@ class _PrivacyRightsPageState extends State { return ListView( children: Permission.values .where((permission) { - return permission == Permission.phone || - permission == Permission.sms; - }) + return permission == Permission.phone || + permission == Permission.sms; + }) .map((permission) => PermissionWidget(permission)) .toList()); } @@ -147,7 +146,7 @@ class _PermissionState extends State { case PermissionStatus.limited: return Colors.orange; default: - return Colors.grey; + return Colors.red; } } @@ -166,11 +165,11 @@ class _PermissionState extends State { Widget build(BuildContext context) { return ListTile( title: Text( - _permission.value == 8 ? title[0] : title[1], + _permission.value==8?title[0]:title[1], style: Theme.of(context).textTheme.titleMedium, ), subtitle: Text( - _permission.value == 8 ? sub[0] : sub[1], + _permission.value==8?sub[0]:sub[1], ), trailing: Wrap( children: [ @@ -202,4 +201,4 @@ class _PermissionState extends State { print(_permissionStatus); }); } -} +} \ No newline at end of file diff --git a/lib/ui/user/user_page.dart b/lib/ui/user/user_page.dart index c519c03..3343d8a 100644 --- a/lib/ui/user/user_page.dart +++ b/lib/ui/user/user_page.dart @@ -1,10 +1,8 @@ import 'package:bot_toast/bot_toast.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart'; -import 'package:power_logger/power_logger.dart'; import 'package:project_telephony/base/base_style.dart'; import 'package:project_telephony/ui/login/login_page.dart'; import 'package:project_telephony/ui/user/members_page.dart'; @@ -28,14 +26,13 @@ class UserPage extends StatefulWidget { final Telephony telephony = Telephony.instance; +@override +void initState() {} + class _UserPageState extends State { bool vle = false; - bool tooken = false; - @override - void initState() { - super.initState(); + bool tooken = true; - } @override Widget build(BuildContext context) { @@ -55,10 +52,8 @@ class _UserPageState extends State { _getSwitch(Assets.icons.switch1.path, "功能开关", true), _getSwitch(Assets.icons.privacy.path, "隐私政策", false), _getSwitch(Assets.icons.permissions.path, "权限说明", false), - _getSwitch(Assets.icons.sms.path, "短信标签", false), // const Spacer(), 182.hb, - tooken? PloneBottom( border: false, onTap: () { @@ -68,7 +63,7 @@ class _UserPageState extends State { color1: const Color(0xFFEBF5FF), color2: const Color(0xFFEBF5FF), text: "退出登录", - ):const SizedBox(), + ) ]), ); } diff --git a/lib/utils/hive_store.dart b/lib/utils/hive_store.dart new file mode 100644 index 0000000..d1afcd3 --- /dev/null +++ b/lib/utils/hive_store.dart @@ -0,0 +1,25 @@ +import 'package:flutter/foundation.dart'; +import 'package:hive/hive.dart'; +import 'package:path_provider/path_provider.dart'; + +class HiveStore { + static Box? _appBox; + + static Box? get appBox => _appBox; + static Box? _userBox; + + static Box? get userBox => _userBox; + static Box? _dataBox; + + static Box? get dataBox => _dataBox; + + static Future init() async { + if (!kIsWeb) { + var dir = await getApplicationDocumentsDirectory(); + Hive.init(dir.path); + _appBox = await Hive.openBox('app'); + _userBox = await Hive.openBox('userBox'); + _dataBox = await Hive.openBox('dataBox'); + } + } +} diff --git a/lib/utils/toast/cloud_toast.dart b/lib/utils/toast/cloud_toast.dart new file mode 100644 index 0000000..238a0b8 --- /dev/null +++ b/lib/utils/toast/cloud_toast.dart @@ -0,0 +1,30 @@ + +import 'package:bot_toast/bot_toast.dart'; +import 'package:flutter/material.dart'; + +class CloudToast { + static show(String text,{AlignmentGeometry? align}) { + BotToast.showText( + text: text, + align: align?? const Alignment(0, 0.8), + borderRadius: BorderRadius.circular(20), + ); + } + + static Function get loading { + return BotToast.showCustomLoading( + toastBuilder: (cancel) { + return const Center( + child: Material( + clipBehavior: Clip.antiAlias, + shape: StadiumBorder(), + child: Padding( + padding: EdgeInsets.all(8.0), + child: CircularProgressIndicator(), + ), + ), + ); + }, + ); + } +} diff --git a/lib/utils/user_tool.dart b/lib/utils/user_tool.dart new file mode 100644 index 0000000..f2a64ae --- /dev/null +++ b/lib/utils/user_tool.dart @@ -0,0 +1,8 @@ +import 'package:provider/provider.dart'; +import '../providers/user_provider.dart'; +import 'headers.dart'; + +class UserTool { + static UserProvider userProvider = + Provider.of(Get.context!, listen: false); +} diff --git a/pubspec.lock b/pubspec.lock index e9dca52..9502508 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "40.0.0" + version: "44.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.4.0" archive: dependency: transitive description: @@ -36,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + auto_size_text: + dependency: transitive + description: + name: auto_size_text + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" auto_size_text_pk: dependency: transitive description: @@ -161,7 +168,7 @@ packages: name: code_builder url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.2.0" collection: dependency: transitive description: @@ -232,13 +239,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.0" + device_info: + dependency: transitive + description: + name: device_info + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + device_info_platform_interface: + dependency: transitive + description: + name: device_info_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" device_info_plus: dependency: "direct main" description: name: device_info_plus url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "4.0.1" device_info_plus_linux: dependency: transitive description: @@ -273,7 +294,7 @@ packages: name: device_info_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "3.0.1" dio: dependency: transitive description: @@ -281,6 +302,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.6" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" fake_async: dependency: transitive description: @@ -294,7 +322,7 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "2.0.1" file: dependency: transitive description: @@ -376,7 +404,7 @@ packages: name: flutter_lints url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "1.0.4" flutter_native_splash: dependency: "direct dev" description: @@ -471,13 +499,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - hive_generator: - dependency: "direct dev" - description: - name: hive_generator - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" http: dependency: transitive description: @@ -541,13 +562,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.6.1" - import_sorter: - dependency: "direct dev" - description: - name: import_sorter - url: "https://pub.dartlang.org" - source: hosted - version: "4.6.0" intl: dependency: transitive description: @@ -589,7 +603,7 @@ packages: name: lints url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.1" logger: dependency: transitive description: @@ -639,6 +653,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -653,48 +674,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" - package_info_plus: - dependency: transitive - description: - name: package_info_plus - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.2" - package_info_plus_linux: - dependency: transitive - description: - name: package_info_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - package_info_plus_macos: - dependency: transitive - description: - name: package_info_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - package_info_plus_web: - dependency: transitive - description: - name: package_info_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - package_info_plus_windows: - dependency: transitive - description: - name: package_info_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" path: dependency: transitive description: @@ -750,7 +729,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.7" + version: "2.1.1" permission_handler: dependency: "direct main" description: @@ -792,7 +771,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "4.4.0" + version: "5.0.0" platform: dependency: transitive description: @@ -820,7 +799,7 @@ packages: name: power_logger url: "https://pub.dartlang.org" source: hosted - version: "1.2.2" + version: "1.2.0" process: dependency: transitive description: @@ -828,6 +807,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.3" pub_semver: dependency: "direct dev" description: @@ -1022,13 +1008,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" - tint: - dependency: transitive - description: - name: tint - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" tobias: dependency: "direct main" description: @@ -1042,7 +1021,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" universal_io: dependency: transitive description: @@ -1091,7 +1070,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.5.2" + version: "2.7.0" xdg_directories: dependency: transitive description: @@ -1105,7 +1084,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.3.1" + version: "5.4.1" yaml: dependency: "direct dev" description: @@ -1114,5 +1093,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.17.0-206.0.dev <3.0.0" - flutter: ">=2.8.1" + dart: ">=2.17.0 <3.0.0" + flutter: ">=3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8cab645..0ff7908 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -69,8 +69,10 @@ dependencies: # model生成 json_annotation: ^4.6.0 permission_handler_platform_interface: ^3.7.0 - #日志输出 - power_logger: ^1.2.2 + power_logger: ^1.2.0 + provider: ^6.0.3 + equatable: any + # # jdk # jverify: ^2.2.5 ## pub 集成 @@ -86,17 +88,14 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. # test: ^1.21.4 - #导入包整理 - import_sorter: ^4.5.1 - hive_generator: ^1.1.0 + flutter_lints: ^1.0.0 #model自动生成 json_serializable: ^6.1.3 build_runner: ^2.0.2 yaml: ^3.1.0 pub_semver: ^2.1.0 flutter_gen_runner: ^4.1.3 - flutter_lints: ^2.0.0 -# patgh: ^1.8.1 + # patgh: ^1.8.1 #脚本工具 grinder: ^0.9.1 flutter_native_splash: ^1.1.8+4 diff --git a/test/widget_test.dart b/test/widget_test.dart index 5e067c3..1e94965 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -7,13 +7,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:project_telephony/main.dart'; +// import 'package:test/test.dart'; +import 'package:project_telephony/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/tool/_build.dart b/tool/_build.dart index 9354b5c..249976d 100644 --- a/tool/_build.dart +++ b/tool/_build.dart @@ -37,15 +37,10 @@ buildApkDev() async { 'BUILD_TYPE=Dev', ], ); - String date = DateUtil.formatDate(DateTime.now(), format: 'yy_MM_dd_HH_mm'); - String version = await getVersion(); - await runAsync('rm', arguments: ['-rf', Config.apkDevDir]); - await runAsync('mkdir', arguments: ['-p', Config.apkDevDir]); - await runAsync('mv', arguments: [ Config.buildPath, '${Config.apkDevDir}/${Config.packageName}_${version}_beta_$date.apk'