验证码登录

dyb
戴余标 2 years ago
parent 8fd5a9614a
commit 99c86eb158

@ -58,11 +58,6 @@ android {
// signingConfig signingConfigs.release
// }
}
lintOptions {
disable 'InvalidPackage'
checkReleaseBuilds false
abortOnError false
}
}
flutter {

@ -30,9 +30,9 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- <uses-permission android:name="android.permission.INTERNET"/>-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

@ -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';
}

@ -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');

@ -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<void> initializeService() async {
@ -105,8 +99,11 @@ class _MyAppState extends State<MyApp> {
@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<MyApp> {
@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<SystemUiOverlayStyle>(
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<SystemUiOverlayStyle>(
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()],
));
},
)),
);
}
}

@ -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<String, dynamic> json) =>
_$LoginInfoFromJson(json);
const LoginInfo({
required this.token,
required this.user,
});
@override
List<Object?> 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<String, dynamic> json) => _$UserFromJson(json);
@override
List<Object?> get props =>
[
id,
name,
];
}

@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'login_info_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
LoginInfo _$LoginInfoFromJson(Map<String, dynamic> json) => LoginInfo(
token: json['token'] as String,
user: User.fromJson(json['user'] as Map<String, dynamic>),
);
Map<String, dynamic> _$LoginInfoToJson(LoginInfo instance) => <String, dynamic>{
'token': instance.token,
'user': instance.user,
};
User _$UserFromJson(Map<String, dynamic> json) => User(
id: json['id'] as int,
name: json['name'] as String,
);
Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
};

@ -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 = <String, dynamic>{};
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<BaseModel> 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<BaseListModel> 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<String> 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<List<String>> uploadFiles(
// List<File> files,
// ) async {
// List<String> urls = [];
// if (files.isEmpty) {
// return [];
// } else {
// for (var item in files) {
// String path = await uploadImage(item);
// if (path.isNotEmpty) {
// urls.add(path);
// }
// }
// }
// return urls;
// }
}

@ -0,0 +1,51 @@
import 'package:json_annotation/json_annotation.dart';
part 'base_list_model.g.dart';
@JsonSerializable()
class BaseListModel<T> {
final int code;
final String msg;
final ListInnerModel? data;
BaseListModel({
required this.code,
required this.msg,
required this.data,
});
factory BaseListModel.fromJson(Map<String, dynamic> 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<dynamic>? list;
final int total;
ListInnerModel({
this.list,
required this.total,
});
factory ListInnerModel.fromJson(Map<String, dynamic> json) =>
_$ListInnerModelFromJson(json);
}

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'base_list_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BaseListModel<T> _$BaseListModelFromJson<T>(Map<String, dynamic> json) =>
BaseListModel<T>(
code: json['code'] as int,
msg: json['msg'] as String,
data: json['data'] == null
? null
: ListInnerModel.fromJson(json['data'] as Map<String, dynamic>),
);
Map<String, dynamic> _$BaseListModelToJson<T>(BaseListModel<T> instance) =>
<String, dynamic>{
'code': instance.code,
'msg': instance.msg,
'data': instance.data,
};
ListInnerModel _$ListInnerModelFromJson(Map<String, dynamic> json) =>
ListInnerModel(
list: json['list'] as List<dynamic>?,
total: json['total'] as int,
);
Map<String, dynamic> _$ListInnerModelToJson(ListInnerModel instance) =>
<String, dynamic>{
'list': instance.list,
'total': instance.total,
};

@ -0,0 +1,36 @@
import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';
part 'base_model.g.dart';
@JsonSerializable()
class BaseModel<T> {
int code;
String msg;
dynamic data;
BaseModel({
required this.code,
required this.msg,
this.data,
});
List<T> map(T Function(dynamic json) f) {
if (data == null) return [];
return (data! as List<T>).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<String, dynamic> json) =>
_$BaseModelFromJson(json) as BaseModel<T>;
}

@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'base_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BaseModel<T> _$BaseModelFromJson<T>(Map<String, dynamic> json) => BaseModel<T>(
code: json['code'] as int,
msg: json['msg'] as String,
data: json['data'],
);
Map<String, dynamic> _$BaseModelToJson<T>(BaseModel<T> instance) =>
<String, dynamic>{
'code': instance.code,
'msg': instance.msg,
'data': instance.data,
};

@ -0,0 +1,21 @@
class LoginModel {
String? message;
String? token;
bool? status;
LoginModel({this.message, this.token, this.status});
LoginModel.fromJson(Map<String, dynamic> json) {
message = json['message'];
token = json['token'];
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['message'] = this.message;
data['token'] = this.token;
data['status'] = this.status;
return data;
}
}

@ -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<UserProvider>(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);
}
}

@ -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<String, dynamic> json) =>
_$UserInfoModelFromJson(json);
Map<String, dynamic> toJson() => _$UserInfoModelToJson(this);
static UserInfoModel get fail => const UserInfoModel(
id: 0,
name: '',
phone: '',
status: 0,
vip: Vip(start: '', end: ''),
);
@override
List<Object> 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<String, dynamic> json) => _$VipFromJson(json);
Map<String, dynamic> toJson() => _$VipToJson(this);
@override
List<Object?> get props => [start, end];
}

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_info_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
UserInfoModel _$UserInfoModelFromJson(Map<String, dynamic> 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<String, dynamic>),
);
Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'phone': instance.phone,
'status': instance.status,
'vip': instance.vip,
};
Vip _$VipFromJson(Map<String, dynamic> json) => Vip(
start: json['start'] as String,
end: json['end'] as String,
);
Map<String, dynamic> _$VipToJson(Vip instance) => <String, dynamic>{
'start': instance.start,
'end': instance.end,
};

@ -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<bool> 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();
}
}

@ -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; //truefalse
@ -23,17 +15,6 @@ class ContentPage extends StatefulWidget {
}
class _ContentPageState extends State<ContentPage> {
// static const platform=const MethodChannel("sendSms");
// Future<Null> sendSms( String text) async{
// print("sendSMS");
// try{
// final String result=await platform.invokeMethod('send',<String,dynamic> {"phone":"+8613486828191","msg":text});
// print(result);
// } on PlatformException catch(e){
// print(e.toString());
// }
// }
// SmsManager smsManager = SmsManager.getDefault();
int _select = 0;
List<String> textList = ['欢迎你的来电', '祝您生活愉快', '感谢您的来电我们会尽快处理的', '自定义短信内容'];
List<String> textList1 = ['自定义短信内容'];
@ -79,33 +60,15 @@ class _ContentPageState extends State<ContentPage> {
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<ContentPage> {
);
});
}
setState(() {});
},
child: Container(
// width: 686.w,

@ -11,7 +11,6 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
@ -20,11 +19,12 @@ class _HomePageState extends State<HomePage> {
body: SafeArea(
child: Column(
children: [
Image.asset(
Container(
child: Image.asset(
Assets.images.homeBg.path,
height: 722.w,
width: 722.w,
),
)),
_getBody(),
],
),

@ -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<LoginPage> {
// String _operator="";
// String _phone="";
bool _chooseAgreement = false;
bool _getCodeEnable = true;
late Timer _timer;
@ -33,24 +37,39 @@ class _LoginPageState extends State<LoginPage> {
///
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<UserProvider>(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<LoginPage> {
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<LoginPage> {
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<LoginPage> {
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<LoginPage> {
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<LoginPage> {
//textfieldiOSplaceholder
hintText: "请输入验证码",
//
hintStyle: TextStyle(color: Colors.black12),
hintStyle: const TextStyle(color: Colors.black12),
),
),
);

@ -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<PrivacyRightsPage> {
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<PermissionWidget> {
case PermissionStatus.limited:
return Colors.orange;
default:
return Colors.grey;
return Colors.red;
}
}
@ -166,11 +165,11 @@ class _PermissionState extends State<PermissionWidget> {
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: [

@ -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<UserPage> {
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<UserPage> {
_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<UserPage> {
color1: const Color(0xFFEBF5FF),
color2: const Color(0xFFEBF5FF),
text: "退出登录",
):const SizedBox(),
)
]),
);
}

@ -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');
}
}
}

@ -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(),
),
),
);
},
);
}
}

@ -0,0 +1,8 @@
import 'package:provider/provider.dart';
import '../providers/user_provider.dart';
import 'headers.dart';
class UserTool {
static UserProvider userProvider =
Provider.of<UserProvider>(Get.context!, listen: false);
}

@ -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"

@ -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

@ -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);

@ -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'

Loading…
Cancel
Save