王亚玲 2 years ago
commit e9a50f1496

@ -60,6 +60,12 @@ class _App {
///
String get updateAdd => '/manage/update/add';
///
String get psdAdd=>'/app/register';
///
String get psdLogin=>'/app/loginByPwd';
}
class _Content {

@ -8,6 +8,7 @@ class UserInfoModel extends Equatable {
final int id;
final String name;
final String phone;
final int havePwd;
final int isVip;
final int isTrial;
final String tag;
@ -26,6 +27,7 @@ class UserInfoModel extends Equatable {
id: 0,
name: '',
phone: '',
havePwd: 0,
isVip: 0,
isTrial: 0,
tag: '',
@ -40,6 +42,7 @@ class UserInfoModel extends Equatable {
required this.id,
required this.name,
required this.phone,
required this.havePwd,
required this.isVip,
required this.isTrial,
required this.tag,
@ -55,6 +58,7 @@ class UserInfoModel extends Equatable {
id,
name,
phone,
havePwd,
isVip,
isTrial,
tag,

@ -11,6 +11,7 @@ UserInfoModel _$UserInfoModelFromJson(Map<String, dynamic> json) =>
id: json['id'] as int,
name: json['name'] as String,
phone: json['phone'] as String,
havePwd: json['havePwd'] as int,
isVip: json['is_vip'] as int,
isTrial: json['is_trial'] as int,
tag: json['tag'] as String,
@ -30,6 +31,7 @@ Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) =>
'id': instance.id,
'name': instance.name,
'phone': instance.phone,
'havePwd': instance.havePwd,
'is_vip': instance.isVip,
'is_trial': instance.isTrial,
'tag': instance.tag,

@ -6,13 +6,18 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/ui/login/login_psd_page.dart';
import 'package:project_telephony/ui/user/set_password_page.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 '../../model/network/base_model.dart';
import '../../providers/user_provider.dart';
import '../../utils/toast/cloud_toast.dart';
import '../../utils/user_tool.dart';
import '../tab_navigator.dart';
@ -21,8 +26,7 @@ import '../widget/image_scaffold.dart';
import '../widget/plone_bottom.dart';
class LoginPage extends StatefulWidget {
const
LoginPage({Key? key}) : super(key: key);
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
@ -40,8 +44,8 @@ class _LoginPageState extends State<LoginPage> {
int _countDownNum = 59;
late TextEditingController _phoneController;
late TextEditingController _smsCodeController;
late TextEditingController _pwdCodeController;
late FocusNode _phoneFocusNode;
late FocusNode _smsCodeFocusNode;
bool _cantSelected = false;
DateTime? _lastTap;
@ -53,7 +57,7 @@ class _LoginPageState extends State<LoginPage> {
_smsCodeFocusNode = FocusNode();
_phoneController = TextEditingController();
_smsCodeController = TextEditingController();
// final userProvider = Provider.of<UserProvider>(context, listen: false);
_pwdCodeController = TextEditingController();
var env = const String.fromEnvironment('ENV', defaultValue: 'dev');
if (kDebugMode) {
print('env :$env');
@ -70,11 +74,13 @@ class _LoginPageState extends State<LoginPage> {
_smsCodeFocusNode.unfocus();
_phoneController.dispose();
_smsCodeController.dispose();
_pwdCodeController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CloudScaffold(
systemStyle: const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
@ -116,9 +122,26 @@ class _LoginPageState extends State<LoginPage> {
style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)),
),
80.hb,
_getBox('+86', 36, _phoneTFWidget()),
_getBox('验证码', 32, _codeWidget()),
112.hb,
LoginBoxWidget(text: '+86', fontSize: 36, plone: _phoneTFWidget()),
LoginBoxWidget(text: '验证码', fontSize: 32, plone: _codeWidget()),
Row(
children: [
const Spacer(),
TextButton(
onPressed: () {
Get.to(()=>const LoginPsdPage());
},
child: const Text(
'密码登录',
style: TextStyle(
fontSize: 15,
decoration: TextDecoration.underline,
),
),
),
],
),
60.hb,
PloneBottom(
blM: false,
border: _phoneController.text.length != 11,
@ -132,8 +155,8 @@ class _LoginPageState extends State<LoginPage> {
} else if (!_chooseAgreement) {
BotToast.showText(text: "请同意并勾选隐私政策");
} else {
if (_lastTap != null && DateTime.now().difference(_lastTap!).inSeconds < 2) {
if (_lastTap != null &&
DateTime.now().difference(_lastTap!).inSeconds < 2) {
// BotToast.showText(text: "过快");
return;
}
@ -145,6 +168,9 @@ class _LoginPageState extends State<LoginPage> {
if (base.code == 0) {
await UserTool.userProvider.setToken(base.data['token']);
Get.offAll(const TabNavigator());
if (UserTool.userProvider.userInfo.havePwd == 0) {
Get.to(()=>const SetPasswordPage());
}
} else {
CloudToast.show(base.msg);
}
@ -160,39 +186,6 @@ class _LoginPageState extends State<LoginPage> {
);
}
_getBox(String text, int fontSize, Widget plone) {
return Container(
height: 144.w,
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 48.w),
decoration: BoxDecoration(
// color: Colors.black12,
border: Border(
bottom: BorderSide(color: const Color(0xFFE8E8E8), width: 1.w),
),
),
child: Row(children: [
SizedBox(
width: 112.w,
child: Text(
text,
style: TextStyle(
fontSize: fontSize.sp,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
),
),
Container(
width: 2.w,
height: 48.w,
margin: EdgeInsets.symmetric(horizontal: 32.w),
color: const Color(0xFFE8E8E8),
),
plone,
]),
);
}
//
_phoneTFWidget() {
return SizedBox(
@ -366,3 +359,50 @@ class _LoginPageState extends State<LoginPage> {
);
}
}
class LoginBoxWidget extends StatelessWidget {
final String text;
final int fontSize;
final Widget plone;
const LoginBoxWidget(
{Key? key,
required this.text,
required this.fontSize,
required this.plone})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: 144.w,
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 48.w),
decoration: BoxDecoration(
// color: Colors.black12,
border: Border(
bottom: BorderSide(color: const Color(0xFFE8E8E8), width: 1.w),
),
),
child: Row(children: [
SizedBox(
width: 112.w,
child: Text(
text,
style: TextStyle(
fontSize: fontSize.sp,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
),
),
Container(
width: 2.w,
height: 48.w,
margin: EdgeInsets.symmetric(horizontal: 32.w),
color: const Color(0xFFE8E8E8),
),
plone,
]),
);
}
}

@ -0,0 +1,266 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:project_telephony/extensions/num_ext.dart';
import 'package:project_telephony/ui/login/login_page.dart';
import '../../base/base_style.dart';
import '../../constants/api.dart';
import '../../gen/assets.gen.dart';
import '../../model/network/api_client.dart';
import '../../utils/toast/cloud_toast.dart';
import '../../utils/user_tool.dart';
import '../tab_navigator.dart';
import '../user/content_authority_page.dart';
import '../widget/image_scaffold.dart';
import '../widget/plone_back_button.dart';
import '../widget/plone_bottom.dart';
class LoginPsdPage extends StatefulWidget {
const LoginPsdPage({Key? key}) : super(key: key);
@override
_LoginPsdPageState createState() => _LoginPsdPageState();
}
class _LoginPsdPageState extends State<LoginPsdPage> {
bool _chooseAgreement = false;
late TextEditingController _phoneController;
late TextEditingController _pwdController;
DateTime? _lastTap;
late bool _showPwd = true;
@override
void initState() {
super.initState();
_phoneController = TextEditingController();
_pwdController = TextEditingController();
}
@override
void dispose() {
_phoneController.dispose();
_pwdController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CloudScaffold(
systemStyle: const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
),
path: Assets.images.bg.path,
appbar: Row(
children: [
Padding(
padding: EdgeInsets.only(top: 88.w, left: 8.w),
child: const CloudBackButton(isSpecial: true),
),
Padding(
padding: EdgeInsets.only(left: 186.w, top: 88.w),
child: Text(
"",
style: TextStyle(
fontSize: BaseStyle.fontSize34,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
))
],
),
extendBody: true,
body: Container(
padding: EdgeInsets.only(left: 64.w, right: 64.w, top: 124.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"短信帮手",
style: TextStyle(
fontSize: 64.sp,
fontWeight: FontWeight.bold,
color: Colors.black),
),
32.hb,
Text(
"希望能成为您的短信小助手",
style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)),
),
80.hb,
LoginBoxWidget(text: "+86", fontSize: 36, plone: _phoneTFWidget()),
LoginBoxWidget(text: "密码", fontSize: 32, plone: _pwdWidget()),
Row(
children: [
const Spacer(),
TextButton(
onPressed: () {
Get.to(() => const LoginPage());
},
child: const Text(
'验证码登录',
style: TextStyle(
fontSize: 15,
decoration: TextDecoration.underline,
),
),
),
],
),
60.hb,
PloneBottom(
blM: false,
border: _phoneController.text.length != 11,
opacity: _phoneController.text.length == 11 ? 1 : 0.4,
onTap: () async {
// DateTime? _lastTap;
if (_phoneController.text.length < 11) {
BotToast.showText(text: "请输入手机号");
} else if (!_chooseAgreement) {
BotToast.showText(text: "请同意并勾选隐私政策");
} else {
if (_lastTap != null &&
DateTime.now().difference(_lastTap!).inSeconds < 2) {
// BotToast.showText(text: "过快");
return;
}
_lastTap = DateTime.now();
var base = await apiClient.request(API.app.psdLogin, data: {
'phone': _phoneController.text,
'password': _pwdController.text
});
if (base.code == 0) {
await UserTool.userProvider.setToken(base.data['token']);
Get.offAll(const TabNavigator());
} else {
CloudToast.show(base.msg);
}
}
},
text: "立即登录",
),
32.hb,
_getText()
],
),
),
);
}
_getText() {
return GestureDetector(
onTap: () {
_chooseAgreement = !_chooseAgreement;
setState(() {});
},
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.only(top: 6.w, right: 5.w),
child: !_chooseAgreement
? const Icon(CupertinoIcons.circle,
size: 18, color: Color(0xFFdddddd))
: const Icon(CupertinoIcons.checkmark_circle,
size: 18, color: Colors.blue),
),
RichText(
text: TextSpan(
text: "我已阅读并同意",
style:
TextStyle(color: BaseStyle.colorcccccc, fontSize: 12 * 2.sp),
children: [
TextSpan(
text: '《短信帮手隐私协议》',
style: TextStyle(color: kPrimaryColor, fontSize: 12 * 2.sp),
recognizer: _recognizer(context, 2)),
],
),
),
],
),
);
}
_recognizer(context, int type) {
final TapGestureRecognizer recognizer = TapGestureRecognizer();
recognizer.onTap = () {
if (kDebugMode) {
Get.to(() => const ContentAuthorityPage());
// print("点击协议了");
}
///
};
return recognizer;
}
_phoneTFWidget() {
return SizedBox(
// alignment: Alignment.centerLeft,
// padding: EdgeInsets.symmetric(horizontal: 72.w),
width: 430.w,
height: 50.w,
child: TextField(
maxLength: 11,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))],
textCapitalization: TextCapitalization.none,
onChanged: (text) {
_phoneController.text = text;
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 20.w),
border: InputBorder.none,
counterText: "",
//textfieldiOSplaceholder
hintText: "请输入手机号",
//
hintStyle: const TextStyle(color: Colors.black12),
),
),
);
}
_pwdWidget() {
return SizedBox(
width: 430.w,
height: 50.w,
child: TextField(
obscureText: _showPwd,
maxLength: 16,
textCapitalization: TextCapitalization.none,
onChanged: (text) {
_pwdController.text = text;
setState(() {});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 20.w),
border: InputBorder.none,
counterText: "",
hintText: "请输入密码",
//
hintStyle: const TextStyle(color: Colors.black12),
suffixIcon: IconButton(
padding: EdgeInsets.zero,
onPressed: () {
_showPwd = !_showPwd;
setState((){});
},
icon: Icon(Icons.remove_red_eye,color: _showPwd?Colors.black38:Colors.blue,),
),
),
),
);
}
}

@ -0,0 +1,159 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/utils/headers.dart';
import '../../constants/api.dart';
import '../../model/network/api_client.dart';
import '../../model/network/base_model.dart';
import '../widget/scaffold_theme_widget.dart';
class SetPasswordPage extends StatefulWidget {
const SetPasswordPage({Key? key}) : super(key: key);
@override
_SetPasswordPageState createState() => _SetPasswordPageState();
}
class _SetPasswordPageState extends State<SetPasswordPage> {
late TextEditingController _psdController;
late TextEditingController _psdTwiceController;
final _isOk=false;
static bool isLoginPassword(String input) {
RegExp mobile = RegExp(r"(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$");
return mobile.hasMatch(input);
}
@override
void initState() {
super.initState();
_psdController = TextEditingController();
_psdTwiceController = TextEditingController();
}
@override
void dispose() {
_psdController.dispose();
_psdTwiceController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ScaffoldThemeWidget(
title: "设置密码",
bottom: "确认",
onTap: () async {
if(_psdController.text==_psdTwiceController.text){
BaseModel res = await apiClient.request(API.app.psdAdd,
data: {"password": _psdController.text});
if(res.code==0){
BotToast.showText(text: "设置成功");
}else{
BotToast.showText(text:"设置密码出错");
}
Get.back();
}else{
BotToast.showText(text: "两次输入的密码不相同");
}
},
isOpacity:_psdController.text.isNotEmpty&&isLoginPassword(_psdController.text),
child: Container(
padding: EdgeInsets.all(40.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
'新 密 码 ',
style: TextStyle(
fontSize: 30.sp,
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 10.w),
child: TextField(
maxLength: 16,
onChanged: (value){
_psdController.text=value;
_psdController.value = TextEditingValue(
text: _psdController.text,
selection:
TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream,
offset:
_psdController.text.length,
)));
setState((){});
},
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9_]'))],
controller: _psdController,
decoration: const InputDecoration(
counterText: '',
hintText: '填写新密码',
hintStyle: TextStyle(
color: Colors.black38,
),
),
),
)
,
),
],
),
20.hb,
Row(
children: [
Text(
'确认密码 ',
style: TextStyle(
fontSize: 30.sp,
),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 10.w),
child: TextField(
onChanged: (value){
_psdTwiceController.text=value;
_psdTwiceController.value = TextEditingValue(
text: _psdTwiceController.text,
selection:
TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream,
offset:
_psdTwiceController.text.length,
)));
setState((){});
},
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9_]'))],
controller: _psdTwiceController,
decoration: const InputDecoration(
hintText: '再次确认密码',
hintStyle: TextStyle(
color: Colors.black38,
),
),
),
)
,
),
],
),
20.hb,
Text(
'密码必须是616位字母、数字、字符的组合',
style: TextStyle(
fontSize: 26.sp,
color: Colors.black38,
),
),
],
),
),
);
}
}

@ -0,0 +1,78 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:project_telephony/ui/user/set_password_page.dart';
import 'package:project_telephony/ui/widget/scaffold_theme_widget.dart';
import 'package:project_telephony/utils/user_tool.dart';
class SettingPage extends StatefulWidget {
const SettingPage({Key? key}) : super(key: key);
@override
_SettingPageState createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return ScaffoldThemeWidget(
title: "个人信息",
child: Container(
padding: EdgeInsets.all(40.w),
child: Column(
children: [
Row(
children: [
const Text(
'手机号',
style: TextStyle(
fontSize: 18,
),
),
const Spacer(),
Text(
UserTool.userProvider.userInfo.phone,
style: const TextStyle(
fontSize: 18,
color: Colors.black38,
),
),
Icon(
Icons.arrow_forward_ios,
size: 30.w,
),
],
),
const Divider(),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){
Get.to(()=>const SetPasswordPage());
},
child: Row(
children: [
const Text(
'密码',
style: TextStyle(
fontSize: 18,
),
),
const Spacer(),
Icon(
Icons.arrow_forward_ios,
size: 30.w,
),
],
),
),
const Divider(),
],
),
),
onTap: () {},
);
}
}

@ -12,6 +12,8 @@ import 'package:project_telephony/ui/tab_navigator.dart';
import 'package:project_telephony/ui/user/content_authority_page.dart';
import 'package:project_telephony/ui/user/members_page.dart';
import 'package:project_telephony/ui/user/privacy_rights_page.dart';
import 'package:project_telephony/ui/user/set_password_page.dart';
import 'package:project_telephony/ui/user/setting_page.dart';
import 'package:project_telephony/ui/user/user_card_page.dart';
import 'package:project_telephony/ui/widget/image_scaffold.dart';
import 'package:project_telephony/ui/widget/plone_bottom.dart';
@ -215,6 +217,8 @@ class _UserPageState extends State<UserPage> {
onTap: () {
if (!userProvider.isLogin) {
Get.to(() => const LoginPage());
} else {
Get.to(() => const SettingPage());
}
},
child: Column(
@ -235,8 +239,9 @@ class _UserPageState extends State<UserPage> {
UserTool.userProvider.isLogin ? "欢迎您登录短信帮手" : "登录获取更多信息",
style: TextStyle(
fontSize: BaseStyle.fontSize28,
color: BaseStyle.color333333),
)
color: BaseStyle.color333333,
),
),
],
),
),

@ -1,6 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:project_telephony/model/sms_content_model.dart';
import 'package:project_telephony/utils/user_tool.dart';
import 'package:provider/provider.dart';
import 'package:velocity_x/velocity_x.dart';
import '../../base/base_style.dart';
import '../widget/plone_back_button.dart';
@ -18,7 +22,7 @@ class ScaffoldThemeWidget extends StatefulWidget {
Key? key,
required this.title,
required this.child,
required this.bottom,
this.bottom='',
this.isBorder = true,
this.isOpacity = true,
required this.onTap,
@ -51,13 +55,15 @@ class _ScaffoldThemeWidgetState extends State<ScaffoldThemeWidget> {
backgroundColor: kForeGroundColor),
backgroundColor: Colors.white,
body: widget.child,
bottomNavigationBar:
PloneBottom(
bottomNavigationBar:Offstage(
offstage: widget.bottom.isEmpty,
child: PloneBottom(
onTap: widget.onTap,
border: widget.isBorder,
opacity: widget.isOpacity ? 1 : 0.4,
text: widget.bottom,
).paddingOnly(bottom: 30.w),
)
);
}
}

Loading…
Cancel
Save