@@ -1,13 +0,0 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/widgets.dart'; | |||
class EmptyPage extends StatelessWidget { | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
body: Center( | |||
child: Text('页面未注册'), | |||
), | |||
); | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:zhiying_comm/pages/empty_page/bloc/empty_page_repository.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
import 'empty_page_state.dart'; | |||
import 'empty_page_event.dart'; | |||
class EmptyPageBloc extends Bloc<EmptyPageEvent, EmptyPageState> { | |||
@override | |||
EmptyPageState get initialState => EmptyPageInitial(); | |||
EmptyPageRepository repository; | |||
EmptyPageBloc(this.repository); | |||
@override | |||
Stream<EmptyPageState> mapEventToState( | |||
EmptyPageEvent event, | |||
) async* { | |||
if (event is EmptyPageInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
} | |||
/// 初始化 | |||
Stream<EmptyPageState> _mapInitEventToState(EmptyPageInitEvent event) async* { | |||
var cache = await repository.fetchCacheData(); | |||
if (!EmptyUtil.isEmpty(cache)) { | |||
yield EmptyPageLoadedState(model: cache); | |||
} | |||
var result = await repository.fetchNetData(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield EmptyPageLoadedState(model: result); | |||
} else { | |||
yield EmptyPageErrorState(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
import 'package:meta/meta.dart'; | |||
@immutable | |||
abstract class EmptyPageEvent {} | |||
class EmptyPageInitEvent extends EmptyPageEvent{} |
@@ -0,0 +1,38 @@ | |||
import 'dart:convert'; | |||
import 'package:zhiying_comm/pages/empty_page/model/empty_page_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class EmptyPageRepository { | |||
/// 获取网络数据 | |||
Future<EmptyPageModel> fetchNetData() async { | |||
try { | |||
var result = await NetUtil.post('/api/v1/mod/pub.flutter.empty_page', method: NetMethod.GET, cache: true); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
var modListData = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list'][0]['data']; | |||
if (!EmptyUtil.isEmpty(modListData)) { | |||
return EmptyPageModel.fromJson(jsonDecode(modListData)); | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 获取缓存的数据 | |||
Future<EmptyPageModel> fetchCacheData() async { | |||
try { | |||
var result = await NetUtil.getRequestCachedData('/api/v1/mod/pub.flutter.empty_page'); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
var modListData = result['mod_list'][0]['data']; | |||
if (!EmptyUtil.isEmpty(modListData)) { | |||
return EmptyPageModel.fromJson(jsonDecode(modListData)); | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,15 @@ | |||
import 'package:meta/meta.dart'; | |||
import 'package:zhiying_comm/pages/empty_page/model/empty_page_model.dart'; | |||
@immutable | |||
abstract class EmptyPageState {} | |||
class EmptyPageInitial extends EmptyPageState {} | |||
class EmptyPageLoadedState extends EmptyPageState { | |||
EmptyPageModel model; | |||
EmptyPageLoadedState({this.model}); | |||
} | |||
class EmptyPageErrorState extends EmptyPageState {} |
@@ -0,0 +1,129 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:zhiying_comm/pages/empty_page/bloc/empty_page_bloc.dart'; | |||
import 'package:zhiying_comm/pages/empty_page/model/empty_page_model.dart'; | |||
import 'package:zhiying_comm/util/update/app_update_util.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||
import 'bloc/empty_page_bloc.dart'; | |||
import 'bloc/empty_page_event.dart'; | |||
import 'bloc/empty_page_state.dart'; | |||
import 'bloc/empty_page_repository.dart'; | |||
class EmptyPage extends StatelessWidget { | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocProvider<EmptyPageBloc>( | |||
create: (_) => EmptyPageBloc(EmptyPageRepository())..add(EmptyPageInitEvent()), | |||
child: _EmptyPageContainer(), | |||
); | |||
} | |||
} | |||
class _EmptyPageContainer extends StatefulWidget { | |||
@override | |||
__EmptyPageContainerState createState() => __EmptyPageContainerState(); | |||
} | |||
class __EmptyPageContainerState extends State<_EmptyPageContainer> { | |||
/// 返回 or 升级 | |||
void _buttonClick(String text) { | |||
if(!EmptyUtil.isEmpty(text) && text == 'update'){ | |||
// 更新 | |||
AppUpdateUtil.updateApp(context, needToast: true, mustShowDialog: true); | |||
}else { | |||
// 返回 | |||
Navigator.maybePop(context); | |||
} | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocBuilder<EmptyPageBloc, EmptyPageState>( | |||
builder: (context, state) { | |||
if (state is EmptyPageLoadedState) { | |||
return _buildMainWidget(state?.model); | |||
} | |||
return _buildMainWidget(null); | |||
}, | |||
); | |||
} | |||
Widget _buildMainWidget(EmptyPageModel model) { | |||
return Scaffold( | |||
backgroundColor: HexColor.fromHex(model?.bgColor ?? '#F9F9F9'), | |||
appBar: AppBar( | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
size: 22, | |||
color: HexColor.fromHex(model?.appBarNameColor ?? '#333333'), | |||
), | |||
onPressed: () => Navigator.maybePop(context), | |||
), | |||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||
centerTitle: true, | |||
title: Text( | |||
model?.appBarName ?? '开发中', | |||
style: TextStyle(fontSize: 15, color: HexColor.fromHex(model?.appBarNameColor ?? '#333333'), fontWeight: FontWeight.bold), | |||
), | |||
elevation: 0, | |||
), | |||
body: Padding( | |||
padding: const EdgeInsets.symmetric(horizontal: 36), | |||
child: Column( | |||
children: <Widget>[ | |||
/// 图片 | |||
Padding( | |||
padding: const EdgeInsets.only(top: 125), | |||
child: Container( | |||
height: 200, | |||
width: double.infinity, | |||
child: CachedNetworkImage( | |||
imageUrl: model?.bgImg ?? '', | |||
), | |||
)), | |||
/// 提示文字 | |||
Padding( | |||
padding: const EdgeInsets.only(top: 16, left: 30, right: 30), | |||
child: Text( | |||
model?.contentText ?? '程序员小哥正在开发中,敬请期待', | |||
maxLines: 2, | |||
textAlign: TextAlign.center, | |||
style: TextStyle(color: HexColor.fromHex(model?.contentTextColor ?? '#999999'), fontSize: 14), | |||
)), | |||
/// 按钮 | |||
Padding( | |||
padding: const EdgeInsets.only(top: 16), | |||
child: GestureDetector( | |||
onTap: ()=>_buttonClick(model?.btnType), | |||
behavior: HitTestBehavior.opaque, | |||
child: Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(30), | |||
boxShadow: [ | |||
BoxShadow( | |||
color: HexColor.fromHex('#FF2020'), | |||
blurRadius: 0.5, | |||
) | |||
], | |||
gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ | |||
HexColor.fromHex(model?.btnColor1 ?? '#FF6868'), | |||
HexColor.fromHex(model?.btnColor2 ?? '#FF4242'), | |||
])), | |||
padding: const EdgeInsets.symmetric(horizontal: 43, vertical: 7.5), | |||
child: Text( | |||
model?.btnText ?? '返回', | |||
style: TextStyle(color: HexColor.fromHex(model?.btnTextColor ?? '#FFFFFF'), fontSize: 13), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
), | |||
); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
class EmptyPageModel { | |||
String appBarName; | |||
String appBarNameColor; | |||
String appBarBgColor; | |||
String bgColor; | |||
String bgImg; | |||
String contentText; | |||
String contentTextColor; | |||
String btnColor1; | |||
String btnColor2; | |||
String btnText; | |||
String btnTextColor; | |||
String btnType; | |||
EmptyPageModel({ | |||
this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgColor, | |||
this.bgColor, | |||
this.bgImg, | |||
this.contentText, | |||
this.contentTextColor, | |||
this.btnColor1, | |||
this.btnColor2, | |||
this.btnText, | |||
this.btnTextColor, | |||
this.btnType, | |||
}); | |||
EmptyPageModel.fromJson(Map<String, dynamic> json) { | |||
appBarName = json['app_bar_name']; | |||
appBarNameColor = json['app_bar_name_color']; | |||
appBarBgColor = json['app_bar_bg_color']; | |||
bgColor = json['bg_color']; | |||
bgImg = json['bg_img']; | |||
contentText = json['content_text']; | |||
contentTextColor = json['content_text_color']; | |||
btnColor1 = json['btn_color1']; | |||
btnColor2 = json['btn_color2']; | |||
btnText = json['btn_text']; | |||
btnTextColor = json['btn_text_color']; | |||
btnType = json['btn_type']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['app_bar_name'] = this.appBarName; | |||
data['app_bar_name_color'] = this.appBarNameColor; | |||
data['app_bar_bg_color'] = this.appBarBgColor; | |||
data['bg_color'] = this.bgColor; | |||
data['bg_img'] = this.bgImg; | |||
data['content_text'] = this.contentText; | |||
data['content_text_color'] = this.contentTextColor; | |||
data['btn_color1'] = this.btnColor1; | |||
data['btn_color2'] = this.btnColor2; | |||
data['btn_text'] = this.btnText; | |||
data['btn_text_color'] = this.btnTextColor; | |||
data['btn_type'] = this.btnType; | |||
return data; | |||
} | |||
} |
@@ -57,10 +57,11 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
void _openInvitePage() { | |||
print('跳转到邀请码页面'); | |||
RouterUtil.hideKeyboard(context); | |||
Navigator.push(context, CupertinoPageRoute( | |||
// builder: (_) => PageFactory.create('login_invite', null) | |||
builder: (_) => LoginInvitePage() | |||
)); | |||
Navigator.push( | |||
context, | |||
CupertinoPageRoute( | |||
// builder: (_) => PageFactory.create('login_invite', null) | |||
builder: (_) => LoginInvitePage())); | |||
} | |||
/// 登陆成功页面 | |||
@@ -85,9 +86,11 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
print('登陆'); | |||
if (_checkParam(true)) { | |||
if (_useVcode) { | |||
BlocProvider.of<LoginAccountBloc>(context).add(LoginAccountTypeVcodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '', captcha: _vcodeEdController?.text?.toString()?.trim() ?? '')); | |||
BlocProvider.of<LoginAccountBloc>(context) | |||
.add(LoginAccountTypeVcodeEvent(mobile: _phoneEdController?.text?.toString()?.trim() ?? '', captcha: _vcodeEdController?.text?.toString()?.trim() ?? '')); | |||
} else { | |||
BlocProvider.of<LoginAccountBloc>(context).add(LoginAccountTypePasswordEvent(username: _phoneEdController?.text?.toString()?.trim() ?? '', password: _passEdController?.text?.toString()?.trim() ?? '')); | |||
BlocProvider.of<LoginAccountBloc>(context) | |||
.add(LoginAccountTypePasswordEvent(username: _phoneEdController?.text?.toString()?.trim() ?? '', password: _passEdController?.text?.toString()?.trim() ?? '')); | |||
} | |||
} | |||
} | |||
@@ -257,7 +260,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
buildWhen: (prev, current) { | |||
// 验证码登陆失败 | |||
if (current is LoginAccountTypeVcodeLoginErrorState) { | |||
Fluttertoast.showToast(msg: '登陆失败'); | |||
// Fluttertoast.showToast(msg: '登陆失败'); | |||
return false; | |||
} | |||
// 验证码登陆成功 | |||
@@ -265,7 +268,8 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
/// 缓存登陆数据 | |||
Provider.of<UserInfoNotifier>(context, listen: false)?.setUserInfo(current.model); | |||
if (current?.model?.registerInviteCodeEnable != '1') { | |||
Fluttertoast.showToast(msg: '登陆成功~'); | |||
Fluttertoast.showToast(msg: '登录成功~'); | |||
/// 打开也买 | |||
_openLoginSuccessPage(); | |||
} else { | |||
@@ -339,6 +343,7 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
Widget _getAppBarWidget(LoginModel model) { | |||
return AppBar( | |||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||
brightness: Brightness.light, | |||
elevation: 0, | |||
title: Text( | |||
model?.mobile?.appBarTitle ?? '登录', | |||
@@ -449,6 +454,8 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
return Container( | |||
height: 42, | |||
child: _getCustomInputWidget( | |||
obscureText: true, | |||
keyboardType: TextInputType.text, | |||
controller: _passEdController, | |||
focusNode: _passFN, | |||
onChanged: _onChange, | |||
@@ -543,8 +550,18 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
} | |||
/// 自定义输入框 | |||
Widget _getCustomInputWidget( | |||
{String hint, String hintColor, String bgColor, String textColor, String iconUrl, TextEditingController controller, ValueChanged<String> onChanged, FocusNode focusNode}) { | |||
Widget _getCustomInputWidget({ | |||
String hint, | |||
String hintColor, | |||
String bgColor, | |||
String textColor, | |||
String iconUrl, | |||
TextEditingController controller, | |||
ValueChanged<String> onChanged, | |||
FocusNode focusNode, | |||
TextInputType keyboardType, | |||
bool obscureText = false, | |||
}) { | |||
var border = OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide(color: HexColor.fromHex(bgColor), width: 0)); | |||
return Container( | |||
@@ -564,13 +581,14 @@ class _LoginAccountPageContianerState extends State<LoginAccountPageContianer> i | |||
), | |||
Expanded( | |||
child: TextField( | |||
obscureText: obscureText ?? false, | |||
controller: controller, | |||
focusNode: focusNode, | |||
onChanged: onChanged, | |||
expands: false, | |||
style: TextStyle(color: HexColor.fromHex(textColor)), | |||
maxLines: 1, | |||
keyboardType: TextInputType.number, | |||
keyboardType: keyboardType ?? TextInputType.number, | |||
decoration: InputDecoration( | |||
contentPadding: EdgeInsets.only(top: 30, left: 7.5), | |||
hintText: hint, | |||
@@ -185,6 +185,7 @@ class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> { | |||
/// appBar | |||
Widget _getAppBar(LoginModel model) { | |||
return AppBar( | |||
brightness: Brightness.light, | |||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||
elevation: 0, | |||
title: Text( | |||
@@ -159,6 +159,7 @@ class _LoginQuickContainerPageState extends State<LoginQuickContainerPage> { | |||
/// appBar | |||
Widget _getAppBarWidget() { | |||
return AppBar( | |||
brightness: Brightness.light, | |||
backgroundColor: Colors.transparent, | |||
elevation: 0, | |||
leading: Icon( | |||
@@ -1,7 +1,7 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/services.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:zhiying_comm/pages/empty_page.dart'; | |||
import 'package:zhiying_comm/pages/empty_page/empty_page.dart'; | |||
class NativeUtil { | |||
// 工厂模式 | |||
@@ -22,6 +22,34 @@ class TurnChainUtil { | |||
/// provider: 商品的渠道 | |||
/// data: 转链需要的请求参数 | |||
/// | |||
/// 一些常用的APP的 URL scheme: | |||
/// 来源:https://blog.csdn.net/jdazy/article/details/79208754 | |||
/// QQ: mqq:// | |||
/// 微信: weixin:// | |||
/// 京东: openapp.jdmobile:// | |||
/// 淘宝: taobao:// | |||
/// 美团: imeituan:// | |||
/// 点评: dianping:// | |||
/// 1号店: wccbyihaodian:// | |||
/// 支付宝: alipay:// | |||
/// 微博: sinaweibo:// | |||
/// 腾讯微博: TencentWeibo:// | |||
/// weico微博: weico:// | |||
/// 知乎: zhihu:// | |||
/// 豆瓣fm: doubanradio:// | |||
/// 网易公开课: ntesopen:// | |||
/// Chrome: googlechrome:// | |||
/// QQ浏览器: mqqbrowser:// | |||
/// uc浏览器: ucbrowser:// | |||
/// 搜狗浏览器: SogouMSE:// | |||
/// 百度地图: baidumap:// bdmap:// | |||
/// 优酷: youku:// | |||
/// 人人: renren:// | |||
/// 我查查: wcc:// | |||
/// 有道词典: yddictproapp:// | |||
/// 微盘: sinavdisk:// | |||
/// 名片全能王: camcard:// | |||
/// | |||
static Future<void> openReceiveCoupon(BuildContext context, UserInfoModel userInfoModel, String provider, Map<String, dynamic> data) async { | |||
/// 1、先判断是否登陆 | |||
if (EmptyUtil.isEmpty(userInfoModel) || EmptyUtil.isEmpty(userInfoModel?.token)) { | |||
@@ -62,7 +90,9 @@ class TurnChainUtil { | |||
break; | |||
case GlobalConfig.PROVIDER_JD: | |||
if (!EmptyUtil.isEmpty(openAppUrl) && !EmptyUtil.isEmpty(appUrl) && await canLaunch(appUrl)) { | |||
String tempURLScheme1 = 'openapp.jdmobile://virtual?params=%'; | |||
String tempURLScheme2 = 'openapp.jdmobile://'; | |||
if (!EmptyUtil.isEmpty(openAppUrl) && await canLaunch(tempURLScheme1) || await canLaunch(tempURLScheme2)) { | |||
Jdsdk.openUrl(url: openAppUrl); | |||
} else if (!EmptyUtil.isEmpty(webUrl)) { | |||
RouterUtil.openWebview(webUrl, context); | |||
@@ -11,7 +11,7 @@ export 'models/user/user_info_model.dart'; | |||
export 'models/user/user_info_model_notifier.dart'; | |||
export 'models/user/user_info_model_notifier.dart'; | |||
export 'native/native_router.dart'; | |||
export 'pages/empty_page.dart'; | |||
export 'pages/empty_page/empty_page.dart'; | |||
export 'util/application.dart'; | |||
export 'util/defalut_widget_creater.dart'; | |||
export 'util/empty_util.dart'; | |||