基础库
 
 
 
 
 

357 lines
11 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_bloc/flutter_bloc.dart';
  4. import 'package:provider/provider.dart';
  5. import 'package:zhiying_comm/pages/login_page/model/login_style_model.dart';
  6. import 'package:zhiying_comm/util/empty_util.dart';
  7. import 'package:zhiying_comm/util/mob_util/mob_util.dart';
  8. import 'package:zhiying_comm/zhiying_comm.dart';
  9. import 'bloc/bloc.dart';
  10. import 'bloc/login_invite_repository.dart';
  11. import 'model/login_invite_user.dart';
  12. ///
  13. /// 邀请页面
  14. ///
  15. class LoginInvitePage extends StatelessWidget {
  16. @override
  17. Widget build(BuildContext context) {
  18. return Scaffold(
  19. resizeToAvoidBottomInset: false,
  20. backgroundColor: HexColor.fromHex('#FFFFFF'),
  21. body: BlocProvider(
  22. create: (_) => LoginInviteBloc(repostitory: LoginInviteRepository())..add(LoginInviteInitEvent()),
  23. child: LoginInvitePageContainer(),
  24. ),
  25. );
  26. }
  27. }
  28. ///
  29. /// 邀请
  30. class LoginInvitePageContainer extends StatefulWidget {
  31. @override
  32. _LoginInvitePageContainerState createState() => _LoginInvitePageContainerState();
  33. }
  34. class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> {
  35. TextEditingController _editingController;
  36. FocusNode _focusNode;
  37. bool _showInviteInfo = false;
  38. // 是否登录中
  39. bool _isLogging = false;
  40. /// 返回上一页
  41. void _openPop() {
  42. if (Navigator.canPop(context)) {
  43. Navigator.pop(context);
  44. }
  45. }
  46. /// 注册成功跳转
  47. void _successJump() {
  48. RouterUtil.hideKeyboard(context);
  49. RouterUtil.goBackHomePage(context);
  50. // Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (BuildContext context) => PageFactory.create('homePage', null)), (Route<dynamic> route) => false,);
  51. }
  52. /// 输入框输入变化
  53. void _onChange(String string) {
  54. setState(() {
  55. _showInviteInfo = false;
  56. });
  57. print('$string');
  58. if (!EmptyUtil.isEmpty(string) && string.length >= 3) {
  59. _queryInviteInfo(string);
  60. }
  61. }
  62. /// 查询邀请人
  63. void _queryInviteInfo(String inviteNum) {
  64. if (!EmptyUtil.isEmpty(inviteNum) && inviteNum.length < 3) {
  65. return;
  66. }
  67. BlocProvider.of<LoginInviteBloc>(context).add(LoginInviteQueryEvent(num: inviteNum));
  68. }
  69. /// 填写邀请啊吗
  70. void _submitOnClick(LoginInviteUser inviteUser) async {
  71. _focusNode.unfocus();
  72. if (!_isLogging) {
  73. /// 邀请码
  74. String inviteNum = inviteUser?.userId ?? '';
  75. /// 手机号
  76. UserInfoModel model = await Provider.of<UserInfoNotifier>(context, listen: false)?.getUserInfoModel();
  77. String mobile = model?.mobile ?? '';
  78. if (!EmptyUtil.isEmpty(inviteNum) && !EmptyUtil.isEmpty(mobile)) {
  79. setState(() {
  80. _isLogging = true;
  81. });
  82. BlocProvider.of<LoginInviteBloc>(context).add(LoginInviteSubmitEvent(mobile: mobile, num: inviteNum));
  83. }
  84. }
  85. }
  86. @override
  87. void initState() {
  88. _editingController = TextEditingController();
  89. // SharedPreferencesUtil.setNetCacheResult(Constants.mobInvitedCode, tgid);
  90. MobUtil.getInvitedCode().then((value) {
  91. _editingController.text = value;
  92. _onChange(value);
  93. });
  94. _focusNode = FocusNode();
  95. super.initState();
  96. }
  97. @override
  98. void didChangeDependencies() {
  99. super.didChangeDependencies();
  100. }
  101. @override
  102. void dispose() {
  103. _editingController?.dispose();
  104. _focusNode?.unfocus();
  105. _focusNode?.dispose();
  106. super.dispose();
  107. }
  108. @override
  109. Widget build(BuildContext context) {
  110. return BlocConsumer<LoginInviteBloc, LoginInviteState>(
  111. listener: (context, state) {},
  112. buildWhen: (previous, current) {
  113. /// 提交失败
  114. if (current is LoginInviteSubmitErrorState) {
  115. _isLogging = false;
  116. return false;
  117. }
  118. /// 数据加载出错
  119. if (current is LoginInviteErrorState) {
  120. return false;
  121. }
  122. /// 查询邀请人失败
  123. if (current is LoginInviteQueryErrorState) {
  124. return false;
  125. }
  126. /// 邀请人查询成功
  127. if (current is LoginInviteQuerySuccessState) {
  128. _showInviteInfo = true;
  129. return true;
  130. }
  131. /// 邀请码成功 跳转
  132. if (current is LoginInviteSubmitSuccess) {
  133. // 缓存数据
  134. Provider.of<UserInfoNotifier>(context, listen: false).setUserInfo(current.model);
  135. _successJump();
  136. return false;
  137. }
  138. return true;
  139. },
  140. builder: (context, state) {
  141. print(state);
  142. if (state is LoginInviteLoadedState) {
  143. return _getMainWidget(state.model, null);
  144. }
  145. if (state is LoginInviteQuerySuccessState) {
  146. return _getMainWidget(state.pageMdel, state.model);
  147. }
  148. /// 骨架屏
  149. return Container();
  150. },
  151. );
  152. }
  153. /// 主视图
  154. Widget _getMainWidget(LoginStyleModel model, LoginInviteUser inviteUser) {
  155. return Column(
  156. children: <Widget>[
  157. /// appbar
  158. _getAppBar(model),
  159. /// 标题
  160. Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 40), child: _getTitleWidget(model)),
  161. /// 输入框
  162. Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30), child: _getInviteInputWidget(model)),
  163. /// 邀请人信息
  164. Visibility(visible: inviteUser != null && _showInviteInfo, child: Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 8), child: _getInviteInfoWidget(inviteUser))),
  165. /// 按钮
  166. Padding(padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30), child: _getSubmiBtnWidget(model, inviteUser)),
  167. ],
  168. );
  169. }
  170. /// appBar
  171. Widget _getAppBar(LoginStyleModel model) {
  172. return AppBar(
  173. brightness: Brightness.light,
  174. backgroundColor: HexColor.fromHex('#FFFFFF'),
  175. elevation: 0,
  176. title: Text(
  177. model?.invite?.appBarTitle ?? '登录',
  178. style: TextStyle(color: HexColor.fromHex(model?.invite?.appBarTitleColor ?? '#333333')),
  179. ),
  180. centerTitle: true,
  181. leading: IconButton(
  182. icon: Icon(
  183. Icons.arrow_back_ios,
  184. size: 22,
  185. color: HexColor.fromHex('#333333'),
  186. ),
  187. onPressed: () => _openPop(),
  188. ),
  189. );
  190. }
  191. /// title
  192. Widget _getTitleWidget(LoginStyleModel model) {
  193. return Align(
  194. alignment: Alignment.centerLeft,
  195. child: Text(
  196. model?.invite?.title ?? '输入邀请码',
  197. style: TextStyle(color: HexColor.fromHex(model?.invite?.titleColor ?? '#333333'), fontSize: 25),
  198. ));
  199. }
  200. /// 邀请码输入框
  201. Widget _getInviteInputWidget(LoginStyleModel model) {
  202. return _getCustomInputWidget(
  203. hint: model?.invite?.inputInviteText ?? '请输入邀请码',
  204. controller: _editingController,
  205. focusNode: _focusNode,
  206. onChanged: _onChange,
  207. hintColor: model?.invite?.inputHintColor ?? '#999999',
  208. bgColor: model?.invite?.inputBgColor ?? '#F7F7F7',
  209. textColor: model?.invite?.inputInviteTextColor ?? '#333333',
  210. iconUrl: model?.invite?.inputInviteIcon ?? '');
  211. }
  212. /// 邀请人信息
  213. Widget _getInviteInfoWidget(LoginInviteUser model) {
  214. return Container(
  215. // height: 77.5,
  216. decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), border: Border.all(color: HexColor.fromHex('#E8E8E8'), width: 0.5)),
  217. padding: const EdgeInsets.all(15),
  218. child: Row(
  219. children: <Widget>[
  220. /// 头像
  221. CircleAvatar(
  222. radius: 23.5,
  223. backgroundImage: CachedNetworkImageProvider(model?.avatar ?? ''),
  224. ),
  225. const SizedBox(width: 13),
  226. Column(
  227. mainAxisAlignment: MainAxisAlignment.spaceAround,
  228. crossAxisAlignment: CrossAxisAlignment.start,
  229. children: <Widget>[
  230. /// 名字
  231. Text(
  232. '${model?.nickname}',
  233. style: TextStyle(color: HexColor.fromHex(model?.nickNameColor), fontSize: 13),
  234. ),
  235. /// 邀请
  236. RichText(
  237. text: TextSpan(text: '邀请您进入', style: TextStyle(fontSize: 11, color: HexColor.fromHex(model?.nickNameColor)), children: [
  238. TextSpan(
  239. text: '${model?.appName}',
  240. style: TextStyle(fontSize: 11, color: HexColor.fromHex(model?.appNameColor)),
  241. ),
  242. ]),
  243. )
  244. ],
  245. )
  246. ],
  247. ),
  248. );
  249. }
  250. /// 按钮
  251. Widget _getSubmiBtnWidget(LoginStyleModel model, LoginInviteUser inviteUser) {
  252. return Material(
  253. child: Container(
  254. height: 52,
  255. width: double.infinity,
  256. color: Colors.white,
  257. child: RaisedButton(
  258. child: Text(
  259. _isLogging ? '进入...' : model?.invite?.btnSubmitText ?? '进入智莺生活',
  260. style: TextStyle(fontSize: 15),
  261. ),
  262. textColor: HexColor.fromHex(model?.invite?.btnSubmitTextColor ?? '#FFFFFF'),
  263. color: HexColor.fromHex(model?.invite?.btnSubmitBgColor ?? '#FF3939'),
  264. disabledColor: HexColor.fromHex(model?.invite?.btnBanBgColor ?? '#F5F5F5'),
  265. disabledTextColor: HexColor.fromHex(model?.invite?.btnBanTextColor ?? '#999999'),
  266. elevation: 5,
  267. shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(52 / 2)),
  268. onPressed: _showInviteInfo && inviteUser != null ? () => _submitOnClick(inviteUser) : null,
  269. ),
  270. ),
  271. );
  272. }
  273. /// 自定义输入框
  274. Widget _getCustomInputWidget(
  275. {String hint, String hintColor, String bgColor, String textColor, String iconUrl, TextEditingController controller, ValueChanged<String> onChanged, FocusNode focusNode}) {
  276. var border = OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide(color: HexColor.fromHex(bgColor), width: 0));
  277. return Container(
  278. height: 42,
  279. padding: const EdgeInsets.symmetric(horizontal: 15),
  280. decoration: BoxDecoration(
  281. color: HexColor.fromHex(bgColor),
  282. borderRadius: BorderRadius.circular(8),
  283. ),
  284. child: Row(
  285. mainAxisAlignment: MainAxisAlignment.start,
  286. crossAxisAlignment: CrossAxisAlignment.center,
  287. children: <Widget>[
  288. CachedNetworkImage(
  289. imageUrl: iconUrl ?? '',
  290. width: 10,
  291. ),
  292. Expanded(
  293. child: TextField(
  294. controller: controller,
  295. focusNode: focusNode,
  296. onChanged: onChanged,
  297. expands: false,
  298. style: TextStyle(color: HexColor.fromHex(textColor)),
  299. maxLines: 1,
  300. keyboardType: TextInputType.number,
  301. decoration: InputDecoration(
  302. contentPadding: EdgeInsets.only(top: 30, left: 7.5),
  303. hintText: hint,
  304. hintStyle: TextStyle(fontSize: 13, color: HexColor.fromHex(hintColor)),
  305. hintMaxLines: 1,
  306. filled: true,
  307. fillColor: Colors.transparent,
  308. border: border,
  309. focusedBorder: border,
  310. enabledBorder: border,
  311. disabledBorder: border,
  312. errorBorder: border,
  313. focusedErrorBorder: border,
  314. ),
  315. ),
  316. ),
  317. ],
  318. ),
  319. );
  320. }
  321. }