Hibok
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

2204 строки
74 KiB

  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:chat/home/fans_page.dart';
  4. import 'package:chat/home/goddess_hot.dart';
  5. import 'package:chat/home/my_headview.dart';
  6. import 'package:chat/home/photo_page.dart';
  7. import 'package:chat/home/rich_title.dart';
  8. import 'package:chat/models/ChatMsg.dart';
  9. import 'package:chat/models/money_change.dart';
  10. import 'package:chat/models/ref_name_provider.dart';
  11. import 'package:chat/models/voucher_change.dart';
  12. import 'package:chat/proto/all.pbserver.dart';
  13. import 'package:chat/utils/ChargeMoney.dart';
  14. import 'package:chat/utils/app_navigator.dart';
  15. import 'package:chat/utils/blacklist_mgr.dart';
  16. import 'package:chat/utils/conversation_table.dart';
  17. import 'package:chat/utils/file_cache_mgr.dart';
  18. import 'package:chat/utils/friend_list_mgr.dart';
  19. import 'package:chat/utils/msgHandler.dart';
  20. import 'package:chat/utils/screen.dart';
  21. import 'package:chat/utils/sp_utils.dart';
  22. import 'package:flutter/material.dart';
  23. import 'package:flutter/rendering.dart';
  24. import 'package:chat/data/WebData.dart';
  25. import 'package:chat/data/constants.dart';
  26. import 'package:chat/generated/i18n.dart';
  27. import 'package:chat/home/InformUser.dart';
  28. import 'package:chat/home/MoneyPage.dart';
  29. import 'package:chat/home/Myprogram.dart';
  30. import 'package:chat/home/VideoPage.dart';
  31. import 'package:chat/home/VipPage.dart';
  32. import 'package:chat/models/UserInfo.dart';
  33. import 'package:chat/utils/CustomUI.dart';
  34. import 'package:chat/utils/MessageMgr.dart';
  35. import 'package:chat/utils/TutorialOverlay.dart';
  36. import 'package:cached_network_image/cached_network_image.dart';
  37. import 'package:flutter/services.dart';
  38. import 'package:image_picker/image_picker.dart';
  39. import 'package:multi_image_picker/multi_image_picker.dart';
  40. import 'package:oktoast/oktoast.dart';
  41. import 'package:permission_handler/permission_handler.dart';
  42. import 'package:provider/provider.dart';
  43. import 'package:share/share.dart';
  44. import '../utils/FullWithButton.dart';
  45. import '../home/EditData.dart';
  46. import '../home/SystemEditPage.dart';
  47. import '../data/UserData.dart';
  48. import '../utils/TokenMgr.dart';
  49. import 'package:dio/dio.dart';
  50. import 'package:chat/utils/HttpUtil.dart';
  51. import 'VerificationCenter.dart';
  52. import 'WhiteAndBlackList.dart';
  53. import "package:chat/utils/PicSwiper.dart";
  54. import 'add_friend.dart';
  55. import 'apply_content_view.dart';
  56. import 'daily_bonus_page.dart';
  57. import 'money_picture_view.dart';
  58. import 'dart:math' as math;
  59. var cardWidth;
  60. var greyColor = const Color(0xFFB2B2B2);
  61. const MaxImgSize = 20;
  62. class ProfilePage extends StatefulWidget {
  63. @required
  64. final userId;
  65. final int fromWhere;
  66. final int addMode;
  67. final int applyId; //好友申请id
  68. ProfilePage(
  69. {Key key,
  70. this.userId,
  71. this.fromWhere,
  72. this.addMode = 0,
  73. this.applyId = 0})
  74. : super(key: key);
  75. _ProfilePageState createState() => _ProfilePageState();
  76. }
  77. class _ProfilePageState extends State<ProfilePage>
  78. with TickerProviderStateMixin {
  79. static const Separate_Size = 10.0;
  80. GlobalKey<ScaffoldState> registKey = new GlobalKey();
  81. UserInfo userInfo = new UserInfo();
  82. TextEditingController nickNameController = new TextEditingController();
  83. bool isMyself = false;
  84. List imgList = [];
  85. bool isCanWatch = false;
  86. bool isMan = true;
  87. bool isAttestation = false;
  88. bool isBuyPicture = false;
  89. bool isVip = false;
  90. bool isSvip = false;
  91. bool isApplying = false; //是否申请中
  92. //约会节目
  93. String dateItem = '';
  94. //期待对象
  95. String lovePeople = '';
  96. //约会范围
  97. String dateRange = '';
  98. //生日
  99. String birthday = '';
  100. //身高数据
  101. String heightStr = '';
  102. //体重数据
  103. String weightStr = '';
  104. //个人介绍
  105. String myMsg = '';
  106. Map wealthData = {
  107. 'CoinValue': 0,
  108. 'IsMember': 0,
  109. };
  110. int myselfImg = 0;
  111. String endTime = '';
  112. bool isLoadingFish = false;
  113. String firstDyImg = ''; //第一条动态的图片
  114. int programId = 0; //是否有一条活跃的节目
  115. bool isblack = false;
  116. bool isAuthority = false; //是否有聊天和查看用户资料的权限
  117. bool isShowAll = false;
  118. getUserInfo({mymsg = ''}) async {
  119. if (mymsg != '' && mymsg != null) {
  120. UserData().basicInfo.ownMsg = mymsg;
  121. }
  122. HttpUtil().getUserInfo(
  123. widget.userId,
  124. (data) async {
  125. print('getUserInfo $data');
  126. if (isMyself) {
  127. saveLocalData(data);
  128. }
  129. userInfo = UserInfo.fromJson(data);
  130. initValues();
  131. isLoadingFish = true;
  132. showMyMsgDialog();
  133. if (mounted) {
  134. setState(() {});
  135. }
  136. },
  137. _buildJoinVip,
  138. () {
  139. if (!isMyself) {
  140. Future.delayed(Duration(milliseconds: 500), () {
  141. Navigator.of(context).pop();
  142. });
  143. }
  144. });
  145. getImg();
  146. if (isMyself) {
  147. HttpUtil().getWealth(context, (data) {
  148. wealthData = data;
  149. endTime = data['MemberEnd'];
  150. if (mounted) {
  151. Provider.of<MoneyChangeProvider>(context)
  152. .initMoney(data['CoinValue']);
  153. Provider.of<VoucherChangeProvider>(context)
  154. .initVoucher(data['Voucher']);
  155. }
  156. });
  157. }
  158. }
  159. saveLocalData(data) {
  160. UserData().basicInfo = UserInfo.fromJson(data);
  161. SPUtils.saveString(
  162. Constants.LocalUsrInfo, jsonEncode(UserData().toJson()).toString());
  163. }
  164. initLocalData() async {
  165. if (isMyself && await SPUtils.get(Constants.LocalUsrInfo) != null) {
  166. isLoadingFish = true;
  167. userInfo = UserData().basicInfo;
  168. initValues();
  169. showMyMsgDialog();
  170. }
  171. }
  172. showMyMsgDialog() {
  173. if (!UserData().isFirstTip &&
  174. (UserData().basicInfo.ownMsg == '' ||
  175. UserData().basicInfo.ownMsg == null) &&
  176. UserData().homemainIndex == 4) {
  177. UserData().isFirstTip = true;
  178. CustomUI.buildOneConfirm(
  179. context, I18n.of(context).personal, I18n.of(context).white_now, () {
  180. Navigator.pop(context);
  181. Navigator.of(context).push(
  182. new MaterialPageRoute(
  183. builder: (context) {
  184. return EditPage(
  185. isEditPage: true,
  186. );
  187. },
  188. ),
  189. );
  190. });
  191. }
  192. }
  193. initValues() {
  194. isMan = userInfo.sex == 1;
  195. isAttestation = userInfo.isAttestation == null || userInfo.isAttestation;
  196. isVip = userInfo.isMember > 0;
  197. isSvip = userInfo.isMember == 2;
  198. isCanWatch = userInfo.infoAut == 0 || userInfo.applyStatus == 1;
  199. isApplying = userInfo.applyStatus == 0;
  200. isblack = userInfo.isBlackList;
  201. isBuyPicture =
  202. (isMyself || userInfo.photoAut == 0 || userInfo.payStatus == 1);
  203. dateItem =
  204. userInfo.program == null ? "" : WebData().getProgram(userInfo.program);
  205. lovePeople = userInfo.hopeObject == null
  206. ? ""
  207. : WebData().getLovePeople(userInfo.hopeObject);
  208. dateRange = WebData().getDateRange(userInfo.meetPlace);
  209. birthday = userInfo.birthday == null ? '' : userInfo.birthday;
  210. isAuthority = userInfo.isAuthority ||
  211. (!UserData().isMan() && UserData().basicInfo.isAttestation) ||
  212. userInfo.distince < 200;
  213. myMsg = userInfo.ownMsg;
  214. }
  215. @override
  216. void initState() {
  217. super.initState();
  218. print('ProfilePage initState');
  219. isMyself = widget.userId == UserData().basicInfo.userId;
  220. messageOn();
  221. initLocalData();
  222. getUserInfo();
  223. }
  224. void initMyController() {}
  225. void _buildJoinVip() {
  226. isLoadingFish = true;
  227. CustomUI.buildOneConfirm(
  228. context, I18n.of(context).only_see, I18n.of(context).joinvip, () {
  229. Navigator.of(context).push(
  230. new MaterialPageRoute(
  231. builder: (context) {
  232. return VipPage();
  233. },
  234. ),
  235. );
  236. }, failcallbak: () {
  237. Navigator.of(context).pop();
  238. });
  239. }
  240. msgBuyVip(data) {
  241. HttpUtil().getWealth(context, (data) {
  242. wealthData = data;
  243. endTime = data['MemberEnd'];
  244. if (mounted) {
  245. Provider.of<MoneyChangeProvider>(context).initMoney(data['CoinValue']);
  246. }
  247. });
  248. }
  249. msgRefreshPhoto(data) {
  250. getImg();
  251. }
  252. msgUpdateData(data) {
  253. print('msgUpdateData $data');
  254. getUserInfo(mymsg: data);
  255. }
  256. msgInformSucess(data) {
  257. if (!isMyself)
  258. CustomUI.buildOneConfirm(
  259. context, I18n.of(context).waiting_results, I18n.of(context).ok, () {
  260. Navigator.of(context).pop();
  261. });
  262. }
  263. msgListDelete(data) {
  264. if (userInfo.dynamicNum > 0) {
  265. if (mounted) {
  266. setState(() {
  267. userInfo.dynamicNum--;
  268. });
  269. }
  270. }
  271. }
  272. void messageOn() {
  273. MessageMgr().on('inform_sucess', msgInformSucess);
  274. MessageMgr().on('refresh_money', msgBuyVip);
  275. MessageMgr().on('refresh_photo', msgRefreshPhoto);
  276. MessageMgr().on('update_data', msgUpdateData);
  277. MessageMgr().on('delete_program', msgListDelete);
  278. MessageMgr().on('post_add_friend', msgAddFriend);
  279. MessageMgr().on('refresh_love_list', msgRefreshLoveList);
  280. MessageMgr().on('refresh_fans_num', msgRefreshFansNum);
  281. MessageMgr().on('change_my_headview', msgChangeMyHeadView);
  282. }
  283. void messageOff() {
  284. MessageMgr().off('inform_sucess', msgInformSucess);
  285. MessageMgr().off('refresh_money', msgBuyVip);
  286. MessageMgr().off('refresh_photo', msgRefreshPhoto);
  287. MessageMgr().off('update_data', msgUpdateData);
  288. MessageMgr().off('delete_program', msgListDelete);
  289. MessageMgr().off('post_add_friend', msgAddFriend);
  290. MessageMgr().off('refresh_love_list', msgRefreshLoveList);
  291. MessageMgr().off('refresh_fans_num', msgRefreshFansNum);
  292. MessageMgr().off('change_my_headview', msgChangeMyHeadView);
  293. }
  294. msgChangeMyHeadView(data) {
  295. if (isMyself) {
  296. userInfo.headimgurl = UserData().basicInfo.headimgurl;
  297. setState(() {});
  298. }
  299. }
  300. msgRefreshFansNum(data) {
  301. setState(() {
  302. if (data['UserId'] == userInfo.userId && userInfo.fans < data['nums']) {
  303. userInfo.fans = data['nums'];
  304. }
  305. });
  306. }
  307. msgRefreshLoveList(data) {
  308. setState(() {
  309. if (data['flag'] == 0) {
  310. isMyself ? userInfo.followNum++ : userInfo.fans++;
  311. } else {
  312. isMyself ? userInfo.followNum-- : userInfo.fans--;
  313. }
  314. });
  315. }
  316. msgAddFriend(data) {
  317. setState(() {
  318. userInfo.isAddFriends = 0;
  319. });
  320. }
  321. @override
  322. void dispose() {
  323. messageOff();
  324. registKey = null;
  325. nickNameController.dispose();
  326. super.dispose();
  327. }
  328. void getImg() async {
  329. var data = {
  330. "visitUserId": UserData().basicInfo.userId,
  331. "userId": widget.userId,
  332. };
  333. data['sign'] = TokenMgr().getSign(data);
  334. Response res = await HttpUtil().post('user/personal/album', data: data);
  335. if (res == null) {
  336. return;
  337. }
  338. Map resData = res.data;
  339. if (resData['code'] == 0) {
  340. imgList = resData['data'] == null ? [] : resData['data'];
  341. if (isMyself) {
  342. UserData().picNum = 0;
  343. for (int i = 0; i < imgList.length; i++) {
  344. if (imgList[i]['Status'] == 1) {
  345. UserData().picNum++;
  346. }
  347. if (imgList[i]['Status'] == 0 || imgList[i]['Status'] == 2) {
  348. UserData().haveReview = true;
  349. }
  350. }
  351. }
  352. if (mounted) {
  353. setState(() {});
  354. }
  355. }
  356. }
  357. //上传相册
  358. void _uploadPhoto() async {
  359. int leftLength = MaxImgSize - imgList.length;
  360. if (leftLength <= 0) {
  361. showToast(I18n.of(context)
  362. .max_upload_size
  363. .replaceFirst('/s1', MaxImgSize.toString()));
  364. return;
  365. }
  366. List<Asset> resultList = List<Asset>();
  367. resultList = await MultiImagePicker.pickImages(
  368. maxImages: leftLength > 9 ? 9 : leftLength,
  369. enableCamera: false,
  370. selectedAssets: [],
  371. cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
  372. materialOptions: MaterialOptions(
  373. actionBarColor: "#50A7F9",
  374. actionBarTitle: "Hibok",
  375. allViewTitle: "",
  376. useDetailsView: true,
  377. selectCircleStrokeColor: "#000000",
  378. ),
  379. );
  380. if (resultList != null && resultList.length > 0) {
  381. List<File> fileList = [];
  382. for (var i = 0; i < resultList.length; i++) {
  383. Asset photoEntity = resultList[i];
  384. print('名字:${photoEntity.name}');
  385. ByteData byteData = await photoEntity.getByteData();
  386. File file = await FileCacheMgr().writeFile(
  387. 'temp-photo-${DateTime.now().millisecondsSinceEpoch}.png',
  388. byteData.buffer.asInt8List(0));
  389. fileList.add(file);
  390. }
  391. print('文件列表${fileList.length}');
  392. Map data = {"type": 2, "userId": UserData().basicInfo.userId};
  393. data['sign'] = TokenMgr().getSign(data);
  394. data['sex'] = UserData().basicInfo.sex;
  395. data['isBurn'] = 0;
  396. Response res = await HttpUtil().uploadFiles(
  397. fileList, data, 'upload/post/postfiles', 'image',
  398. isShowLoading: true);
  399. var resData = res.data;
  400. if (resData['code'] == 0) {
  401. if (resData['data']['msg'] != '' && resData['data']['msg'] != null) {
  402. showToast(resData['data']['msg']);
  403. }
  404. if (resData['msg'].split('|').length != fileList.length) {
  405. showToast(I18n.of(context).hava_error_photo);
  406. }
  407. MessageMgr().emit('refresh_photo');
  408. } else {
  409. showToast(resData['msg']);
  410. }
  411. }
  412. }
  413. showHeadView() {
  414. Navigator.of(context).push(
  415. new MaterialPageRoute(
  416. builder: (context) {
  417. return MyHeadViewPage();
  418. },
  419. ),
  420. );
  421. }
  422. Widget _buildSignIn() {
  423. return Container(
  424. margin: EdgeInsets.only(top: Separate_Size, bottom: Separate_Size),
  425. padding: EdgeInsets.symmetric(horizontal: 10),
  426. child: FullWidthButton(
  427. iconCode: 0xe65c,
  428. iconColor: 0xFFAF60F8,
  429. showRightIcon: true,
  430. title: I18n.of(context).sign_in,
  431. showDivider: false,
  432. onPressed: () {
  433. Navigator.of(context).push(MaterialPageRoute(
  434. builder: (context) {
  435. return DailyBonusPage();
  436. },
  437. ));
  438. },
  439. ),
  440. decoration: BoxDecoration(
  441. color: Colors.white,
  442. border: Border(
  443. top: Constants.GreyBorderSide, bottom: Constants.GreyBorderSide)),
  444. );
  445. }
  446. Widget _buildPicture() {
  447. return FullWidthButton(
  448. iconCode: 0xe689,
  449. iconColor: 0xFFE3AA10,
  450. title: (isMyself
  451. ? I18n.of(context).my_album
  452. : (isMan ? I18n.of(context).his_photo : I18n.of(context).her_photo)),
  453. descriptionColor: Constants.BlueTextColor,
  454. showDivider: false,
  455. showRightIcon: true,
  456. onPressed: () {
  457. Navigator.of(context).push(
  458. new MaterialPageRoute(
  459. builder: (context) {
  460. return PhotoPage(
  461. userInfo: userInfo,
  462. );
  463. },
  464. ),
  465. );
  466. },
  467. );
  468. }
  469. Widget _buildHeadView() {
  470. cardWidth = MediaQuery.of(context).size.width;
  471. return Container(
  472. decoration: BoxDecoration(
  473. color: Colors.white,
  474. border: Border(bottom: Constants.GreyBorderSide)),
  475. child: Container(
  476. decoration: BoxDecoration(
  477. color: Colors.white,
  478. ),
  479. width: MediaQuery.of(context).size.width,
  480. padding: EdgeInsets.only(top: 19),
  481. child: Column(
  482. children: <Widget>[
  483. Row(
  484. crossAxisAlignment: CrossAxisAlignment.center,
  485. children: <Widget>[
  486. _buildHeadImg(),
  487. Column(children: <Widget>[
  488. _buildFans(),
  489. _buildButtonList(),
  490. ])
  491. ],
  492. ),
  493. _buildUserChips(),
  494. _buildAttestation(),
  495. _buildMyMsg(),
  496. ],
  497. ),
  498. ),
  499. );
  500. }
  501. Widget _buildMyMsg() {
  502. double width = Screen.width - 80;
  503. var textStyle = TextStyle(fontSize: 12, color: Color(0xFF333333));
  504. // userInfo.ownMsg =
  505. // '哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈';
  506. bool showAllContent = isExpansion(userInfo.ownMsg, width);
  507. return Container(
  508. padding:
  509. EdgeInsets.only(left: 25.5, bottom: isMyself ? 20 : 5, right: 10),
  510. child: userInfo.ownMsg == null || userInfo.ownMsg == ''
  511. ? (isMyself
  512. ? InkWell(
  513. onTap: () {
  514. Navigator.of(context).push(
  515. new MaterialPageRoute(
  516. builder: (context) {
  517. return EditPage(isEditPage: true);
  518. },
  519. ),
  520. );
  521. },
  522. child: Row(children: <Widget>[
  523. Text(I18n.of(context).msg_tips, style: textStyle),
  524. Transform.rotate(
  525. angle: math.pi * 2,
  526. child: Icon(
  527. IconData(0xe68d,
  528. fontFamily: Constants.IconFontFamily),
  529. color: Color(0xFF717171),
  530. size: 16,
  531. ))
  532. ]))
  533. : Container())
  534. : Row(
  535. crossAxisAlignment: CrossAxisAlignment.start,
  536. children: <Widget>[
  537. Container(
  538. width: width,
  539. child: Text(
  540. userInfo.ownMsg,
  541. style: textStyle,
  542. maxLines: isShowAll ? 10 : 1,
  543. overflow: TextOverflow.ellipsis,
  544. )),
  545. SizedBox(width: 4),
  546. showAllContent
  547. ? InkWell(
  548. onTap: () {
  549. setState(() {
  550. isShowAll = !isShowAll;
  551. });
  552. },
  553. child: Transform.rotate(
  554. angle: isShowAll ? math.pi : 0,
  555. child: Icon(
  556. IconData(0xe684,
  557. fontFamily: Constants.IconFontFamily),
  558. color: Color(0xFF717171),
  559. size: 13,
  560. )))
  561. : Container(),
  562. ],
  563. ));
  564. }
  565. bool isExpansion(String text, double width) {
  566. TextPainter _textPainter = TextPainter(
  567. maxLines: 2,
  568. text: TextSpan(
  569. text: text, style: TextStyle(fontSize: 12.0, color: Colors.black)),
  570. textDirection: TextDirection.ltr)
  571. ..layout(maxWidth: width, minWidth: width);
  572. if (_textPainter.didExceedMaxLines) {
  573. //这里判断 文本是否截断
  574. return true;
  575. } else {
  576. return false;
  577. }
  578. }
  579. Widget _buildBorderButton(String str, double width, callback,
  580. {IconData iconCode, int iconColor = 0xFF181818}) {
  581. return InkWell(
  582. onTap: callback,
  583. child: Container(
  584. alignment: Alignment.center,
  585. decoration: BoxDecoration(
  586. border: Border.all(color: Color(0xB5CCCCCC)),
  587. borderRadius: BorderRadius.circular(14)),
  588. height: 28,
  589. width: width,
  590. child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
  591. iconCode != null
  592. ? Container(
  593. margin: EdgeInsets.only(right: 2),
  594. child: Icon(
  595. iconCode,
  596. size: 16,
  597. color: Color(iconColor),
  598. ))
  599. : Container(),
  600. Text(
  601. str,
  602. style: TextStyle(fontSize: 14),
  603. )
  604. ]),
  605. ));
  606. }
  607. gotoEditPage() {
  608. Navigator.of(context).push(
  609. new MaterialPageRoute(
  610. builder: (context) {
  611. return EditPage(isEditPage: true);
  612. },
  613. ),
  614. );
  615. }
  616. gotoSystemEditPage() {
  617. Navigator.of(context).push(
  618. new MaterialPageRoute(
  619. builder: (context) {
  620. return SystemEditPage();
  621. },
  622. ),
  623. );
  624. }
  625. loveOrCancele() {
  626. if (!userInfo.isLike) {
  627. HttpUtil().setLove(userInfo.userId, () {
  628. MessageMgr()
  629. .emit('refresh_love_list', {'UserId': userInfo.userId, 'flag': 0});
  630. setState(() {
  631. userInfo.isLike = true;
  632. });
  633. });
  634. } else {
  635. HttpUtil().cancleLove(userInfo.userId, () {
  636. MessageMgr()
  637. .emit('refresh_love_list', {'UserId': userInfo.userId, 'flag': 2});
  638. setState(() {
  639. userInfo.isLike = false;
  640. });
  641. });
  642. }
  643. }
  644. Widget _buildButtonList() {
  645. List<Widget> list = [];
  646. if (isMyself) {
  647. list = [
  648. _buildBorderButton(
  649. I18n.of(context).edit_information, 140, gotoEditPage),
  650. SizedBox(width: 12.5),
  651. _buildBorderButton('', 53, gotoSystemEditPage,
  652. iconCode: Icons.settings),
  653. ];
  654. } else if (userInfo.sex == UserData().basicInfo.sex) {
  655. list = [
  656. _buildBorderButton(I18n.of(context).private_chat, 140,
  657. isCanWatch ? buyChatAccount : null,
  658. iconCode: IconData(0xe68c, fontFamily: 'iconfont')),
  659. ];
  660. } else {
  661. list = [
  662. _buildBorderButton(I18n.of(context).like, 140, loveOrCancele,
  663. iconCode: IconData(userInfo.isLike ? 0xe623 : 0xe625,
  664. fontFamily: Constants.IconFontFamily),
  665. iconColor: userInfo.isLike ? 0xFFFF7777 : 0xFF181818),
  666. SizedBox(width: 12.5),
  667. _buildBorderButton('', 53, isCanWatch ? buyChatAccount : null,
  668. iconCode: IconData(0xe68c, fontFamily: 'iconfont')),
  669. ];
  670. }
  671. return Container(
  672. margin: EdgeInsets.only(top: 13, bottom: 10),
  673. child: Row(
  674. children: list,
  675. ));
  676. }
  677. //认证相关
  678. Widget _buildAttestation() {
  679. return Container(
  680. margin: EdgeInsets.only(top: 7, bottom: 7, left: 25.5),
  681. alignment: Alignment.centerLeft,
  682. child: Row(
  683. mainAxisAlignment: MainAxisAlignment.start,
  684. children: <Widget>[
  685. isAttestation
  686. ? Icon(Icons.check_circle_outline,
  687. size: 12, color: Constants.BlueTextColor)
  688. : Padding(
  689. padding: EdgeInsets.only(bottom: 0.5),
  690. child: Icon(IconData(0xe63a, fontFamily: 'iconfont'),
  691. size: 16, color: const Color(0xFFA9A9A9))),
  692. SizedBox(width: 3),
  693. Text(
  694. isAttestation
  695. ? isMyself
  696. ? (isMan
  697. ? (userInfo.isVipAttestation
  698. ? I18n.of(context).by_paying
  699. : I18n.of(context).incode_passed)
  700. : I18n.of(context).certified)
  701. : (isMan
  702. ? (userInfo.isVipAttestation
  703. ? I18n.of(context).pay_join
  704. : I18n.of(context).passed_review)
  705. : I18n.of(context).passed_video)
  706. : isMyself
  707. ? I18n.of(context).not_certified
  708. : (isMan ? '' : I18n.of(context).not_video),
  709. textScaleFactor: 1.0,
  710. style: TextStyle(fontSize: 11, color: Constants.GreyTextColor))
  711. ],
  712. ));
  713. }
  714. Widget _buildFansButton(int nums, String text, callback,
  715. {bool isShowDot = false}) {
  716. return InkWell(
  717. onTap: callback,
  718. child: Container(
  719. width: (Screen.width - 130) / 3,
  720. child: Column(
  721. children: <Widget>[
  722. Stack(
  723. children: <Widget>[
  724. Padding(
  725. padding: EdgeInsets.only(left: 4, right: 4),
  726. child: Text(
  727. nums > 99 ? "99+" : nums.toString(),
  728. style: TextStyle(
  729. fontSize: 13, color: Constants.BlackTextColor),
  730. )),
  731. isShowDot
  732. ? Positioned(
  733. top: 2,
  734. right: 0,
  735. child: CircleAvatar(
  736. radius: 2,
  737. backgroundColor: const Color(0xFFE50000),
  738. ),
  739. )
  740. : Container(
  741. width: 0,
  742. )
  743. ],
  744. ),
  745. SizedBox(height: 4),
  746. Text(
  747. text,
  748. style: TextStyle(fontSize: 11, color: greyColor),
  749. ),
  750. ],
  751. )),
  752. );
  753. }
  754. //关注列表
  755. Widget _buildFans() {
  756. return Container(
  757. child: Row(
  758. children: <Widget>[
  759. _buildFansButton(
  760. userInfo.fans,
  761. I18n.of(context).fans,
  762. isMyself
  763. ? () {
  764. Navigator.of(context).push(
  765. new MaterialPageRoute(
  766. builder: (context) {
  767. return FansPage();
  768. },
  769. ),
  770. );
  771. }
  772. : null),
  773. _buildFansButton(
  774. userInfo.followNum,
  775. I18n.of(context).attention,
  776. isMyself
  777. ? () {
  778. Navigator.of(context).push(
  779. new MaterialPageRoute(
  780. builder: (context) {
  781. return WhiteAndBlackPage(
  782. isWhite: true,
  783. );
  784. },
  785. ),
  786. );
  787. }
  788. : null),
  789. _buildFansButton(userInfo.dynamicNum, I18n.of(context).dynamics, () {
  790. Navigator.of(context).push(
  791. new MaterialPageRoute(
  792. builder: (context) {
  793. return MyProgramPage(
  794. userId: userInfo.userId,
  795. isMan: isMan,
  796. );
  797. },
  798. ),
  799. );
  800. }, isShowDot: userInfo.dynamicNum > 0),
  801. ],
  802. ));
  803. }
  804. Widget _buildDivder() {
  805. return Container(
  806. color: Color(0xFFE6E6E6),
  807. width: 1.5,
  808. height: 10,
  809. margin: EdgeInsets.only(left: 7.5, right: 7.5));
  810. }
  811. //用户chips
  812. Widget _buildUserChips() {
  813. var age = 0;
  814. if (userInfo.birthday != null) {
  815. age = DateTime.now().year - int.parse(userInfo.birthday.split('-')[0]);
  816. }
  817. var textStyle = TextStyle(fontSize: 12);
  818. return Container(
  819. width: Screen.width,
  820. padding: EdgeInsets.only(left: 25.5),
  821. child: Row(
  822. mainAxisAlignment: MainAxisAlignment.start,
  823. children: <Widget>[
  824. isAttestation && !isMan
  825. ? Container(
  826. height: 13,
  827. padding: EdgeInsets.only(left: 5, right: 5),
  828. alignment: Alignment.center,
  829. decoration: BoxDecoration(
  830. borderRadius: BorderRadius.circular(10),
  831. color: Constants.PurpleBackgroundColor,
  832. ),
  833. child: Text(
  834. 'Real',
  835. textScaleFactor: 1.0,
  836. style: TextStyle(fontSize: 9, color: Colors.white),
  837. ))
  838. : Text(''),
  839. isVip && isMan
  840. ? Container(
  841. child: isSvip ? Constants.svipIcon : Constants.vipIcon)
  842. : Text(''),
  843. (isAttestation && !isMan) || isVip && isMan
  844. ? _buildDivder()
  845. : Container(),
  846. Text(
  847. '${UserData().hasLocationPermission ? WebData().getDateRange(userInfo.meetPlace) : I18n.of(context).unknown}',
  848. style: textStyle,
  849. ),
  850. _buildDivder(),
  851. Text(
  852. '$age ${I18n.of(context).years_old}-${WebData().getConstellation(context, userInfo.constellation)}',
  853. style: textStyle,
  854. ),
  855. _buildDivder(),
  856. Text(
  857. userInfo.occupation == null
  858. ? ''
  859. : WebData().getProffesionName(userInfo.occupation),
  860. style: textStyle,
  861. )
  862. ],
  863. ));
  864. }
  865. //用户头像
  866. Widget _buildHeadImg() {
  867. double width = 85;
  868. return InkWell(
  869. onTap: isMyself
  870. ? showHeadView
  871. : () {
  872. Navigator.of(context).push(
  873. new MaterialPageRoute(
  874. builder: (context) {
  875. return PicSwiper(
  876. id: 0,
  877. pics: [PicSwiperItem(userInfo.headimgurl, id: 0)],
  878. );
  879. },
  880. ),
  881. );
  882. },
  883. child: Container(
  884. margin: EdgeInsets.only(left: 19, right: 19, bottom: 15),
  885. decoration: BoxDecoration(shape: BoxShape.circle, boxShadow: [
  886. BoxShadow(
  887. color: Color(0xFFD9D9D9),
  888. offset: Offset(0, 0.5),
  889. blurRadius: 5,
  890. )
  891. ]),
  892. width: width,
  893. height: width,
  894. child: ClipRRect(
  895. borderRadius: BorderRadius.circular(100),
  896. child: userInfo.headimgurl == null || userInfo.headimgurl == ''
  897. ? Image.asset(Constants.DefaultHeadImgUrl,
  898. height: width, width: width)
  899. : CachedNetworkImage(
  900. imageUrl: userInfo.headimgurl,
  901. placeholder: (context, url) => Image.asset(
  902. Constants.DefaultHeadImgUrl,
  903. height: width,
  904. width: width,
  905. ),
  906. fit: BoxFit.cover,
  907. ),
  908. )),
  909. );
  910. }
  911. Widget _buildMyPicture() {
  912. var pisc = imgList
  913. .map((f) => PicSwiperItem(
  914. f['ImgUrl'],
  915. id: f['Id'],
  916. type: f['Type'],
  917. isWatch: f['IsCheck'] == 1,
  918. userId: userInfo.userId,
  919. isBuy: f['PayStatus'] == 1,
  920. isCheck: f['Status'] == 0,
  921. ))
  922. .toList();
  923. var list = imgList.map((data) {
  924. var width = MediaQuery.of(context).size.width / 4 - 15;
  925. bool isWatch = data['IsCheck'] == 1;
  926. double raduis = 10;
  927. return CustomUI.buildImgCover(data['Id'], pisc, data['ImgUrl'], width,
  928. raduis, isWatch, context, data['Type'],
  929. isMyself: isMyself,
  930. payStatus: data['PayStatus'],
  931. state: isMan ? 1 : data['Status']);
  932. }).toList();
  933. if (!isBuyPicture && list.length > 4) {
  934. list.length = 4;
  935. }
  936. TitleItem title;
  937. if (!isMan) {
  938. title = UserData().isVip
  939. ? TitleItem(
  940. title: I18n.of(context).unlock_user,
  941. name: Provider.of<RefNameProvider>(context)
  942. .getRefName(userInfo.userId, userInfo.nickName),
  943. )
  944. : TitleItem(
  945. title: I18n.of(context).free_unlock,
  946. name: userInfo.price.toString() + I18n.of(context).mask_coin);
  947. } else {
  948. title = TitleItem(
  949. title: I18n.of(context).pay_unlock, name: userInfo.price.toString());
  950. }
  951. //我的相册
  952. return Container(
  953. alignment: Alignment.center,
  954. margin: EdgeInsets.only(top: Separate_Size),
  955. padding: EdgeInsets.symmetric(horizontal: 10),
  956. width: isMyself ? Screen.width : cardWidth,
  957. child: Column(
  958. crossAxisAlignment: CrossAxisAlignment.start,
  959. children: <Widget>[
  960. FullWidthButton(
  961. title: (isMyself
  962. ? I18n.of(context).my_album
  963. : (isMan
  964. ? I18n.of(context).his_photo
  965. : I18n.of(context).her_photo)),
  966. description: isMyself
  967. ? '${I18n.of(context).upload}(${imgList.length}/$MaxImgSize)'
  968. : '',
  969. descriptionColor: Constants.BlueTextColor,
  970. showDivider: true,
  971. showRightIcon: false,
  972. onPressed: isMyself ? _uploadPhoto : () {},
  973. ),
  974. list.length == 0
  975. ? (isMyself
  976. ? InkWell(
  977. onTap: _uploadPhoto,
  978. child: Container(
  979. height: 100,
  980. alignment: Alignment.center,
  981. child: Column(
  982. mainAxisAlignment: MainAxisAlignment.center,
  983. children: <Widget>[
  984. Text(I18n.of(context).first_photo,
  985. textScaleFactor: 1.0),
  986. Text(
  987. isMan
  988. ? I18n.of(context).have_picture
  989. : I18n.of(context).no_photo,
  990. textScaleFactor: 1.0,
  991. style: TextStyle(
  992. fontSize: 12, color: Colors.grey))
  993. ],
  994. )))
  995. : Container(
  996. alignment: Alignment.center,
  997. height: 120,
  998. child: Text(
  999. isMan
  1000. ? I18n.of(context).not_up_man
  1001. : I18n.of(context).not_up_women,
  1002. textScaleFactor: 1.0,
  1003. style: TextStyle(fontSize: 14),
  1004. ),
  1005. ))
  1006. : (isBuyPicture
  1007. ? Container(
  1008. //alignment: Alignment.center,
  1009. child: Wrap(
  1010. crossAxisAlignment: WrapCrossAlignment.start,
  1011. children: list,
  1012. ))
  1013. : Container(
  1014. alignment: Alignment.center,
  1015. child: Stack(
  1016. //alignment: Alignment.center,
  1017. children: <Widget>[
  1018. Wrap(
  1019. crossAxisAlignment: WrapCrossAlignment.start,
  1020. children: list,
  1021. ),
  1022. Opacity(
  1023. opacity: 0.96,
  1024. child: Container(
  1025. decoration: BoxDecoration(color: Colors.white),
  1026. height: 200,
  1027. ),
  1028. ),
  1029. Container(
  1030. height: 200,
  1031. alignment: Alignment.center,
  1032. child: Column(
  1033. mainAxisAlignment: MainAxisAlignment.center,
  1034. children: <Widget>[
  1035. Image.asset(
  1036. 'assets/images/suo.png',
  1037. width: 35,
  1038. color: Colors.grey[700],
  1039. ),
  1040. Container(
  1041. margin: EdgeInsets.only(top: 10),
  1042. alignment: Alignment.center,
  1043. child: Text(
  1044. isMan
  1045. ? I18n.of(context).set_lock
  1046. : I18n.of(context).set_lock2,
  1047. textScaleFactor: 1.0,
  1048. style: TextStyle(
  1049. color: Colors.grey[700],
  1050. fontSize: 15),
  1051. ),
  1052. ),
  1053. Container(
  1054. margin: EdgeInsets.only(top: 8),
  1055. alignment: Alignment.center,
  1056. child: RichText(
  1057. text: TextSpan(
  1058. children: RichTitle.getRichText(title,
  1059. titleStyle: TextStyle(
  1060. color: Colors.grey[700],
  1061. fontSize: 13),
  1062. nameStyle: TextStyle(
  1063. color: Colors.red,
  1064. fontSize: 13))),
  1065. ),
  1066. ),
  1067. InkWell(
  1068. onTap: buyPhoto,
  1069. child: Container(
  1070. margin: EdgeInsets.only(top: 10),
  1071. padding:
  1072. EdgeInsets.only(top: 6, bottom: 6),
  1073. width: 100,
  1074. alignment: Alignment.center,
  1075. decoration: Constants
  1076. .ConfirmBUttonBoxDecoration,
  1077. child: Text(
  1078. I18n.of(context).unlock,
  1079. textScaleFactor: 1.0,
  1080. style: TextStyle(color: Colors.white),
  1081. ),
  1082. )),
  1083. ],
  1084. ))
  1085. ],
  1086. ))),
  1087. !isMan && isMyself
  1088. ? InkWell(
  1089. onTap: () {
  1090. if (!userInfo.isAttestation) {
  1091. _buildNotTrue();
  1092. return;
  1093. }
  1094. if (imgList.length == 0) {
  1095. showToast(I18n.of(context).no_photos);
  1096. return;
  1097. }
  1098. var moneyList = [];
  1099. for (int i = 0; i < imgList.length; i++) {
  1100. if (imgList[i]['Status'] == 1) {
  1101. moneyList.add(imgList[i]);
  1102. }
  1103. }
  1104. Navigator.of(context)
  1105. .push(new MaterialPageRoute(builder: (context) {
  1106. return MoneyPicture(
  1107. imageList: moneyList,
  1108. );
  1109. }));
  1110. },
  1111. child: Container(
  1112. alignment: Alignment.centerRight,
  1113. margin: EdgeInsets.only(top: 10, right: 10, bottom: 10),
  1114. padding: EdgeInsets.only(top: 10),
  1115. child: Text(
  1116. I18n.of(context).set_photo,
  1117. textScaleFactor: 1.0,
  1118. style: TextStyle(color: Colors.red),
  1119. ),
  1120. ))
  1121. : Container(),
  1122. ],
  1123. ),
  1124. decoration: BoxDecoration(
  1125. color: Colors.white,
  1126. border: Border(
  1127. top: Constants.GreyBorderSide, bottom: Constants.GreyBorderSide)),
  1128. );
  1129. }
  1130. void _buildNotTrue() {
  1131. CustomUI.buildOneConfirm(context, I18n.of(context).moneyPageTip,
  1132. I18n.of(context).authenticate_now, () {
  1133. Navigator.pop(context);
  1134. Navigator.of(context).push(
  1135. new MaterialPageRoute(
  1136. builder: (context) {
  1137. return VerificationCenterPage();
  1138. },
  1139. ),
  1140. );
  1141. });
  1142. }
  1143. void _buildConfirmBlack() {
  1144. Navigator.of(context).pop();
  1145. CustomUI.buildOneConfirm(
  1146. context, I18n.of(context).blacklist_choose, I18n.of(context).determine,
  1147. () async {
  1148. Navigator.pop(context);
  1149. HttpUtil().blackUser(userInfo.userId, () {
  1150. isblack = true;
  1151. });
  1152. });
  1153. }
  1154. void _sendMySelfPicture() async {
  1155. if (await CustomUI.showPhotoPermissionSetting(context)) {
  1156. var tempFile = await ImagePicker.pickImage(source: ImageSource.gallery);
  1157. if (tempFile != null) {
  1158. Map data = {"type": 6, "userId": UserData().basicInfo.userId};
  1159. data['sign'] = TokenMgr().getSign(data);
  1160. data['isBurn'] = 1;
  1161. Response res = await HttpUtil().uploadFile(
  1162. tempFile, data, 'upload/file/postflie', 'image',
  1163. isShowLoading: true);
  1164. var resData = res.data;
  1165. if (resData['code'] == 0) {
  1166. showToast(I18n.of(context).successfully_submit);
  1167. myselfImg = resData['data']['photoId'];
  1168. Navigator.of(context).pop();
  1169. _postApply();
  1170. }
  1171. }
  1172. }
  1173. }
  1174. void _postApply() async {
  1175. Map data = {
  1176. "userId": userInfo.userId,
  1177. "imgUrl": myselfImg,
  1178. "applyUserId": UserData().basicInfo.userId
  1179. };
  1180. data['sign'] = TokenMgr().getSign(data);
  1181. Response res = await HttpUtil()
  1182. .post('user/apply/checkcords', data: data, isShowLoading: true);
  1183. Map resData = res.data;
  1184. if (resData['code'] == 0) {
  1185. isApplying = true;
  1186. setState(() {});
  1187. }
  1188. }
  1189. Widget _buildBody() {
  1190. Widget hidden = Container(
  1191. alignment: Alignment.center,
  1192. width: Screen.width,
  1193. height: Screen.height - 372,
  1194. color: Colors.white,
  1195. margin: EdgeInsets.only(top: 10),
  1196. child: Column(
  1197. mainAxisAlignment: MainAxisAlignment.center,
  1198. children: <Widget>[
  1199. Container(
  1200. margin: EdgeInsets.only(bottom: 10),
  1201. child: Image.asset('assets/images/login/lock.png',
  1202. height: 45, width: 45),
  1203. ),
  1204. Text(
  1205. isMan ? I18n.of(context).view_user : I18n.of(context).view_user2,
  1206. textScaleFactor: 1.0,
  1207. textAlign: TextAlign.center,
  1208. style: TextStyle(color: Constants.GreyTextColor, fontSize: 13.5),
  1209. ),
  1210. InkWell(
  1211. onTap: isApplying
  1212. ? null
  1213. : () async {
  1214. CustomUI.buildOneConfirm(
  1215. context,
  1216. I18n.of(context).need_photo,
  1217. I18n.of(context).choose_photo,
  1218. _sendMySelfPicture);
  1219. },
  1220. child: Container(
  1221. margin: EdgeInsets.only(top: 10, left: 100, right: 100),
  1222. padding: EdgeInsets.only(top: 10, bottom: 10),
  1223. alignment: Alignment.center,
  1224. decoration: BoxDecoration(
  1225. color: Constants.ConfrimButtonColor,
  1226. borderRadius: BorderRadius.all(
  1227. Radius.circular(Constants.LittleButtonRadius))),
  1228. child: Text(
  1229. isApplying
  1230. ? I18n.of(context).already_applied
  1231. : I18n.of(context).apply_now,
  1232. textScaleFactor: 1.0,
  1233. style: TextStyle(color: Colors.white),
  1234. ),
  1235. )),
  1236. ],
  1237. ),
  1238. );
  1239. List<Widget> child = [];
  1240. if (isMyself) {
  1241. child.addAll([
  1242. _buildHeadView(),
  1243. _buildSignIn(),
  1244. _buildMoneyBox(),
  1245. ]);
  1246. } else if (isCanWatch) {
  1247. child.addAll([
  1248. _buildHeadView(),
  1249. Container(
  1250. margin: EdgeInsets.only(top: Separate_Size, bottom: Separate_Size),
  1251. padding: EdgeInsets.symmetric(horizontal: 10),
  1252. child: _buildPicture(),
  1253. decoration: BoxDecoration(
  1254. color: Colors.white,
  1255. border: Border(
  1256. top: Constants.GreyBorderSide,
  1257. bottom: Constants.GreyBorderSide)),
  1258. ),
  1259. _buildBasicInfo(),
  1260. _buildBottomTips(),
  1261. ]);
  1262. } else if (userInfo.userId != null) {
  1263. child.addAll([
  1264. _buildHeadView(),
  1265. hidden,
  1266. ]);
  1267. } else {
  1268. child.addAll([
  1269. _buildHeadView(),
  1270. ]);
  1271. }
  1272. return Column(
  1273. children: child,
  1274. );
  1275. }
  1276. _inviteFdBtn() {
  1277. return Container(
  1278. width: Screen.width,
  1279. child: FlatButton(
  1280. child: fixedText(I18n.of(context).add_friends,
  1281. fontSize: 16,
  1282. color: Colors.blueAccent,
  1283. fontWeight: FontWeight.w500),
  1284. onPressed: () async {
  1285. //已经是好友
  1286. if (FriendListMgr().isMyFriend(userInfo.userId)) {
  1287. showToast(I18n.of(context).added);
  1288. return;
  1289. }
  1290. //已申请
  1291. if (userInfo.isAddFriends == 0) {
  1292. showToast(I18n.of(context).add_friends_tips);
  1293. return;
  1294. }
  1295. if (widget.addMode != 3 &&
  1296. UserData().addFdDistanceSwitch > 0 &&
  1297. userInfo.distince > 200) {
  1298. showToast(I18n.of(context).distance_long);
  1299. return;
  1300. }
  1301. Navigator.of(context).push(
  1302. new MaterialPageRoute(
  1303. builder: (context) {
  1304. return AddFriendPage(
  1305. userId: userInfo.userId,
  1306. pageType: SendMessagePageType.AddFriends,
  1307. originalName: I18n.of(context)
  1308. .i_am
  1309. .replaceFirst('/s1', UserData().basicInfo.nickName),
  1310. );
  1311. },
  1312. ),
  1313. );
  1314. }),
  1315. );
  1316. }
  1317. void doFriendApply(state, callback) async {
  1318. Map data = {
  1319. "id": widget.applyId,
  1320. "userId": UserData().basicInfo.userId,
  1321. "status": state,
  1322. };
  1323. data['sign'] = TokenMgr().getSign(data);
  1324. Response res =
  1325. await HttpUtil().post('friendship/handler/apply', data: data);
  1326. if (res == null) {
  1327. return;
  1328. }
  1329. var resData = res.data;
  1330. if (resData['code'] == 0) {
  1331. callback(resData['msg']);
  1332. } else {}
  1333. }
  1334. _dealInvite() {
  1335. return Container(
  1336. width: Screen.width,
  1337. child: Row(
  1338. children: <Widget>[
  1339. Expanded(
  1340. child: InkWell(
  1341. onTap: () {
  1342. doFriendApply(1, (msg) {
  1343. showToast(msg);
  1344. Navigator.of(context).pop();
  1345. var friendModel = FriendModel.fromServerJson({
  1346. 'UserId': userInfo.userId,
  1347. 'ImgUrl': userInfo.headimgurl,
  1348. 'UserName': userInfo.nickName
  1349. });
  1350. FriendListMgr().addFriend(friendModel);
  1351. FriendListMgr().deleteLocalUserId();
  1352. MessageMgr().emit('do_friend_apply',
  1353. {'userId': userInfo.userId, 'state': 1});
  1354. MessageMgr().emit('Add friend');
  1355. //同意好友后发送打招呼
  1356. MsgModel msgModel = MsgHandler.createSendMsg(
  1357. ChatType.TextChatType, I18n.of(context).new_friends_tips,
  1358. friendId: userInfo.userId,
  1359. refMsg: null,
  1360. refShortTxt: null,
  1361. altUsers: null,
  1362. channelType: ChatChannelType.Session);
  1363. int sessionId = UserData().getSessionId(userInfo.userId);
  1364. MsgHandler.updateActiveSesstion(sessionId);
  1365. AppNavigator.pushChatPage(context, userInfo.userId,
  1366. enterType: 3, enterContent: msgModel);
  1367. });
  1368. },
  1369. child: Container(
  1370. color: const Color(0xFF3875E9),
  1371. alignment: Alignment.center,
  1372. child: Text(
  1373. I18n.of(context).agree,
  1374. style: TextStyle(fontSize: 18, color: Colors.white),
  1375. ),
  1376. ),
  1377. )),
  1378. InkWell(
  1379. onTap: () {
  1380. doFriendApply(2, (msg) {
  1381. showToast(msg);
  1382. Navigator.of(context).pop();
  1383. MessageMgr().emit('do_friend_apply',
  1384. {'userId': userInfo.userId, 'state': 2});
  1385. });
  1386. },
  1387. child: Container(
  1388. alignment: Alignment.center,
  1389. color: const Color(0xFFA8D3FF),
  1390. width: Screen.width * 0.33,
  1391. child: Text(
  1392. I18n.of(context).refuse,
  1393. style:
  1394. TextStyle(fontSize: 18, color: const Color(0xFF007EFF)),
  1395. ),
  1396. ))
  1397. ],
  1398. ));
  1399. }
  1400. //自定义item
  1401. Widget _bottomBorderBox(
  1402. String textLeft, String textRight, bool showBorder, callback,
  1403. {showIcon: false}) {
  1404. Widget left = new Container(
  1405. margin: EdgeInsets.only(right: 20),
  1406. width: 90,
  1407. child: new Text(
  1408. textLeft,
  1409. textScaleFactor: 1.0,
  1410. style: TextStyle(fontSize: 14),
  1411. ));
  1412. Widget right = new Expanded(
  1413. child: Text(
  1414. textRight,
  1415. textScaleFactor: 1.0,
  1416. style: TextStyle(fontSize: 13, color: Constants.GreyTextColor),
  1417. ),
  1418. );
  1419. return InkWell(
  1420. highlightColor: Colors.transparent,
  1421. radius: 0.0,
  1422. onTap: callback,
  1423. child: Container(
  1424. decoration: showBorder
  1425. ? BoxDecoration(border: Border(bottom: Constants.GreyBorderSide))
  1426. : null,
  1427. alignment: Alignment.center,
  1428. padding: EdgeInsets.only(
  1429. top: 17,
  1430. bottom: 17,
  1431. ),
  1432. margin: EdgeInsets.only(left: 45, bottom: 0, right: 10),
  1433. child: Row(
  1434. crossAxisAlignment: CrossAxisAlignment.start,
  1435. children: <Widget>[
  1436. left,
  1437. right,
  1438. showIcon
  1439. ? Padding(
  1440. padding: EdgeInsets.only(right: 10),
  1441. child: Icon(
  1442. IconData(0xe63c, fontFamily: 'iconfont'),
  1443. size: 22.0,
  1444. color: Color(AppColors.TabIconNormal),
  1445. ))
  1446. : Container()
  1447. ],
  1448. ),
  1449. ));
  1450. }
  1451. testChatPermission(callback) {
  1452. becomeVip() {
  1453. Navigator.of(context).push(
  1454. new MaterialPageRoute(
  1455. builder: (context) {
  1456. return VipPage();
  1457. },
  1458. ),
  1459. );
  1460. }
  1461. payCallback() {
  1462. if (Provider.of<MoneyChangeProvider>(context).money <
  1463. UserData().accountPrice) {
  1464. Navigator.of(context).pop();
  1465. CustomUI.buildOneConfirm(context, I18n.of(context).balance_insufficien,
  1466. I18n.of(context).recharge, () {
  1467. Navigator.of(context).pop();
  1468. ChargeMoney.showChargeSheet(context, () {
  1469. setState(() {});
  1470. });
  1471. });
  1472. return;
  1473. }
  1474. Navigator.of(context).pop();
  1475. HttpUtil().buyChatAccount(
  1476. UserData().accountPrice, userInfo.userId, context, () {
  1477. setState(() {
  1478. isAuthority = true;
  1479. });
  1480. });
  1481. }
  1482. freeTime() {
  1483. HttpUtil().userFreeTime(context, userInfo.userId, 2, () {
  1484. UserData().basicInfo.usedNum++;
  1485. Navigator.of(context).pop();
  1486. setState(() {
  1487. isAuthority = true;
  1488. });
  1489. });
  1490. }
  1491. //自己是女性,且未认证,提示去认证(好友除外)
  1492. if (!UserData().isMan() &&
  1493. !UserData().basicInfo.isAttestation &&
  1494. !FriendListMgr().isMyFriend(userInfo.userId)) {
  1495. CustomUI.buildNotTrue(context);
  1496. return;
  1497. }
  1498. print('isAuthority $isAuthority');
  1499. var tipStr = '';
  1500. //没有解锁账号,并且对方禁止陌生人聊天
  1501. if (!isAuthority && !userInfo.isCanStrangerNews) {
  1502. tipStr = I18n.of(context).stranger_close;
  1503. } else {
  1504. tipStr = I18n.of(context).unlock_information;
  1505. if (userInfo.sex == 2 && !userInfo.isAttestation) {
  1506. tipStr += '(${I18n.of(context).not_true_woman})';
  1507. }
  1508. }
  1509. if (isAuthority) {
  1510. if (callback != null) callback();
  1511. } else {
  1512. //如果自己是男性,vip提示免费次数,次数用完或者非vip提示购买
  1513. if (UserData().isMan()) {
  1514. if (UserData().isVip) {
  1515. UserData().basicInfo.freeNum < UserData().basicInfo.usedNum
  1516. ? CustomUI.buildOneConfirm(
  1517. context,
  1518. tipStr,
  1519. I18n.of(context)
  1520. .pay_unlock
  1521. .replaceFirst('/s1', UserData().accountPrice.toString()),
  1522. payCallback)
  1523. : CustomUI.buildOneConfirm(
  1524. context,
  1525. tipStr,
  1526. I18n.of(context).unlock_choose,
  1527. freeTime,
  1528. );
  1529. } else {
  1530. CustomUI.buildTowConfirm(
  1531. context,
  1532. tipStr,
  1533. I18n.of(context).become_member,
  1534. becomeVip,
  1535. I18n.of(context)
  1536. .pay_unlock
  1537. .replaceFirst('/s1', UserData().accountPrice.toString()),
  1538. payCallback);
  1539. }
  1540. }
  1541. }
  1542. }
  1543. buyChatAccount() {
  1544. if (widget.fromWhere != null && widget.fromWhere == 0) {
  1545. ///如果是聊天界面跳转过来的,直接返回
  1546. Navigator.of(context).pop();
  1547. } else {
  1548. testChatPermission(() {
  1549. int fdId = userInfo.userId;
  1550. int sessionId = UserData().getSessionId(fdId);
  1551. MsgHandler.updateActiveSesstion(sessionId);
  1552. AppNavigator.pushChatPage(context, fdId);
  1553. });
  1554. }
  1555. }
  1556. clickChatAccout() {
  1557. if (widget.fromWhere != null && widget.fromWhere == 0) {
  1558. ///如果是聊天界面跳转过来的,直接返回
  1559. Navigator.of(context).pop();
  1560. } else {
  1561. testChatPermission(() {});
  1562. }
  1563. }
  1564. buyPhoto() {
  1565. //女性用户付费,男性用户会员的话免费解锁,非会员付费解锁
  1566. becomeVip() {
  1567. Navigator.of(context).push(
  1568. new MaterialPageRoute(
  1569. builder: (context) {
  1570. return VipPage();
  1571. },
  1572. ),
  1573. );
  1574. }
  1575. payCallback() {
  1576. if (Provider.of<MoneyChangeProvider>(context).money < userInfo.price) {
  1577. Navigator.of(context).pop();
  1578. CustomUI.buildOneConfirm(context, I18n.of(context).balance_insufficien,
  1579. I18n.of(context).recharge, () {
  1580. Navigator.of(context).pop();
  1581. ChargeMoney.showChargeSheet(context, () {
  1582. setState(() {});
  1583. });
  1584. });
  1585. return;
  1586. }
  1587. Navigator.of(context).pop();
  1588. HttpUtil().buyPictures(userInfo.price, userInfo.userId, context, () {
  1589. setState(() {
  1590. isBuyPicture = true;
  1591. });
  1592. });
  1593. }
  1594. freeTime() {
  1595. HttpUtil().userFreeTime(context, userInfo.userId, 1, () {
  1596. UserData().basicInfo.usedNum++;
  1597. Navigator.of(context).pop();
  1598. setState(() {
  1599. isBuyPicture = true;
  1600. });
  1601. });
  1602. }
  1603. String title = I18n.of(context).unlock_user.replaceFirst(
  1604. '/s1',
  1605. Provider.of<RefNameProvider>(context)
  1606. .getRefName(userInfo.userId, userInfo.nickName),
  1607. );
  1608. if (!UserData().isMan()) {
  1609. CustomUI.buildOneConfirm(
  1610. context,
  1611. title,
  1612. I18n.of(context)
  1613. .pay_unlock
  1614. .replaceFirst('/s1', userInfo.price.toString()),
  1615. payCallback);
  1616. } else if (UserData().isVip) {
  1617. if (UserData().basicInfo.freeNum < UserData().basicInfo.usedNum) {
  1618. CustomUI.buildOneConfirm(
  1619. context,
  1620. title,
  1621. I18n.of(context)
  1622. .pay_unlock
  1623. .replaceFirst('/s1', userInfo.price.toString()),
  1624. payCallback);
  1625. } else {
  1626. CustomUI.buildOneConfirm(
  1627. context, title, I18n.of(context).unlock_choose, freeTime);
  1628. }
  1629. } else {
  1630. CustomUI.buildTowConfirm(
  1631. context,
  1632. title,
  1633. I18n.of(context).become_member,
  1634. becomeVip,
  1635. I18n.of(context)
  1636. .pay_unlock
  1637. .replaceFirst('/s1', userInfo.price.toString()),
  1638. payCallback);
  1639. }
  1640. }
  1641. Widget _buildBasicInfo() {
  1642. String wechat = '';
  1643. String facebook = '';
  1644. bool isHidden = userInfo.accountStatus == 1;
  1645. //隐藏社交账号
  1646. if (isHidden) {
  1647. wechat = I18n.of(context).ask_me;
  1648. facebook = I18n.of(context).ask_me;
  1649. } else {
  1650. wechat = isAuthority ? userInfo.wechat : I18n.of(context).filled_in;
  1651. facebook = isAuthority ? userInfo.facebook : I18n.of(context).filled_in;
  1652. }
  1653. heightStr = (userInfo.height == 0.0 || userInfo.height == null)
  1654. ? I18n.of(context).not_show
  1655. : '${userInfo.height.toInt()}CM';
  1656. weightStr = (userInfo.weight == 0.0 || userInfo.weight == null)
  1657. ? I18n.of(context).not_show
  1658. : '${userInfo.weight.toInt()}KG';
  1659. List<Widget> basicList = [
  1660. Container(
  1661. padding: EdgeInsets.symmetric(horizontal: 10),
  1662. child: FullWidthButton(
  1663. iconCode: 0xe676,
  1664. iconColor: 0xFF57BBFB,
  1665. title: isMan
  1666. ? I18n.of(context).his_profile
  1667. : I18n.of(context).her_profile,
  1668. showDivider: true,
  1669. showRightIcon: false,
  1670. onPressed: () {})),
  1671. userInfo.height != null && userInfo.height != 0
  1672. ? _bottomBorderBox(I18n.of(context).height, heightStr, true, () {})
  1673. : Container(),
  1674. userInfo.weight != null && userInfo.weight != 0
  1675. ? _bottomBorderBox(I18n.of(context).weight, weightStr, true, () {})
  1676. : Container(),
  1677. _bottomBorderBox(I18n.of(context).Resident_city, dateRange, true, () {}),
  1678. _bottomBorderBox(I18n.of(context).expect_lover, lovePeople, true, () {}),
  1679. (userInfo.wechat != null && userInfo.wechat != '')
  1680. ? _bottomBorderBox(
  1681. I18n.of(context).wechat_number, wechat, true, clickChatAccout,
  1682. showIcon: !isAuthority)
  1683. : Container(),
  1684. (userInfo.facebook != null && userInfo.facebook != '')
  1685. ? _bottomBorderBox(
  1686. I18n.of(context).facebook, facebook, true, clickChatAccout,
  1687. showIcon: !isAuthority)
  1688. : Container(),
  1689. ];
  1690. return Container(
  1691. width: cardWidth,
  1692. margin: EdgeInsets.only(top: Separate_Size),
  1693. decoration: BoxDecoration(
  1694. color: Colors.white,
  1695. border: Border(
  1696. top: Constants.GreyBorderSide,
  1697. bottom: Constants.GreyBorderSide)),
  1698. child: new Column(
  1699. children: basicList,
  1700. ));
  1701. }
  1702. Widget _buildBottomTips() {
  1703. return Container(
  1704. margin: EdgeInsets.only(bottom: 10, left: 10, right: 10, top: 10),
  1705. width: cardWidth,
  1706. alignment: Alignment.center,
  1707. child: Text(I18n.of(context).not_illage,
  1708. textScaleFactor: 1.0,
  1709. textAlign: TextAlign.center,
  1710. style: TextStyle(fontSize: 12, color: Colors.grey)),
  1711. );
  1712. }
  1713. Widget _buildMoneyBox() {
  1714. //认证、钱包、隐私连麦设置
  1715. return Container(
  1716. margin: EdgeInsets.only(top: Separate_Size),
  1717. decoration: BoxDecoration(
  1718. color: Colors.white,
  1719. border: Border(
  1720. top: Constants.GreyBorderSide, bottom: Constants.GreyBorderSide)),
  1721. padding: EdgeInsets.only(top: 4, bottom: 4, left: 10, right: 10),
  1722. child: Column(
  1723. children: <Widget>[
  1724. isMan
  1725. ? Container()
  1726. : FullWidthButton(
  1727. iconCode: 0xe687,
  1728. iconColor: 0xFFFF7752,
  1729. title: I18n.of(context).Goddess_heat,
  1730. showDivider: true,
  1731. showRightIcon: true,
  1732. onPressed: () {
  1733. Navigator.of(context).push(
  1734. new MaterialPageRoute(
  1735. builder: (context) {
  1736. return GoddessHotPage(
  1737. userId: userInfo.userId,
  1738. );
  1739. },
  1740. ),
  1741. );
  1742. },
  1743. ),
  1744. isMan
  1745. ? FullWidthButton(
  1746. iconCode: 0xe68e,
  1747. iconColor: 0xFF3D83E6,
  1748. title: I18n.of(context).member,
  1749. description: UserData().isVip
  1750. ? I18n.of(context)
  1751. .expires
  1752. .replaceFirst('/s1', endTime.split(' ')[0])
  1753. : I18n.of(context).enjoy_privileges,
  1754. showDivider: true,
  1755. onPressed: () {
  1756. Navigator.of(context).push(
  1757. new MaterialPageRoute(
  1758. builder: (context) {
  1759. return VipPage();
  1760. },
  1761. ),
  1762. );
  1763. },
  1764. )
  1765. : FullWidthButton(
  1766. iconCode: 0xe688,
  1767. iconColor: 0xFF3D83E6,
  1768. title: isAttestation
  1769. ? I18n.of(context).certified_video
  1770. : I18n.of(context).authenticate,
  1771. showDivider: true,
  1772. onPressed: () {
  1773. Navigator.of(context).push(
  1774. new MaterialPageRoute(
  1775. builder: (context) {
  1776. return isAttestation
  1777. ? VideoPage(
  1778. userId: userInfo.userId,
  1779. )
  1780. : VerificationCenterPage();
  1781. },
  1782. ),
  1783. );
  1784. },
  1785. ),
  1786. FullWidthButton(
  1787. iconCode: 0xe68a,
  1788. iconColor: 0xFF4CB871,
  1789. title: I18n.of(context).wallet,
  1790. description:
  1791. '${Provider.of<MoneyChangeProvider>(context).money}${I18n.of(context).mask_coin}',
  1792. showDivider: true,
  1793. onPressed: () {
  1794. Navigator.of(context).push(
  1795. new MaterialPageRoute(
  1796. builder: (context) {
  1797. return MoneyPage();
  1798. },
  1799. ),
  1800. );
  1801. },
  1802. ),
  1803. _buildPicture(),
  1804. ],
  1805. ),
  1806. );
  1807. }
  1808. Widget _buildIcon(code, str, isCanHit, callback, {iconSize = 28.0}) {
  1809. var color = isCanHit ? Constants.BlueTextColor : Constants.GreyTextColor;
  1810. return InkWell(
  1811. onTap: isCanHit
  1812. ? callback
  1813. : () {
  1814. showToast(isMan
  1815. ? I18n.of(context).view_user
  1816. : I18n.of(context).view_user2);
  1817. },
  1818. child: Row(
  1819. children: <Widget>[
  1820. Icon(
  1821. IconData(
  1822. code,
  1823. fontFamily: 'iconfont',
  1824. ),
  1825. color: color,
  1826. size: iconSize,
  1827. ),
  1828. Padding(
  1829. child: Text(
  1830. str,
  1831. textScaleFactor: 1.0,
  1832. style: TextStyle(color: color, fontSize: 12),
  1833. ),
  1834. padding: EdgeInsets.only(left: 5))
  1835. ],
  1836. ));
  1837. }
  1838. @override
  1839. Widget build(BuildContext context) {
  1840. Size screenSize = MediaQuery.of(context).size;
  1841. cardWidth = screenSize.width;
  1842. Widget appBar = AppBar(
  1843. leading: isMyself ? Container() : CustomUI.buildCustomLeading(context),
  1844. titleSpacing: isMyself ? -40 : NavigationToolbar.kMiddleSpacing,
  1845. title: isMyself
  1846. ? Text(
  1847. userInfo.nickName,
  1848. //I18n.of(context).me,
  1849. textScaleFactor: 1.0,
  1850. style: Constants.MainTitleStyle,
  1851. )
  1852. : Text(
  1853. WebData().subUserName(Provider.of<RefNameProvider>(context)
  1854. .getRefName(userInfo.userId, userInfo.nickName)),
  1855. textScaleFactor: 1.0,
  1856. style: TextStyle(color: Constants.BlackTextColor)),
  1857. centerTitle: !isMyself,
  1858. elevation: 1,
  1859. actions: <Widget>[
  1860. isMyself
  1861. ? Container(
  1862. padding: EdgeInsets.only(right: 15),
  1863. alignment: Alignment.center,
  1864. child: new InkWell(
  1865. child: CircleAvatar(
  1866. backgroundColor: Constants.GreyBackgroundColor,
  1867. radius: 15.75,
  1868. child: Icon(
  1869. IconData(0xe685, fontFamily: 'iconfont'),
  1870. color: Constants.BlackTextColor,
  1871. size: 20,
  1872. )),
  1873. onTap: () {
  1874. Share.share('https://henho.jphgames.com/');
  1875. },
  1876. ),
  1877. )
  1878. : Container(),
  1879. isMyself
  1880. ? Container()
  1881. : Container(
  1882. alignment: Alignment.center,
  1883. child: new InkWell(
  1884. child: new Padding(
  1885. padding: EdgeInsets.only(
  1886. right: 15, left: 15, top: 10, bottom: 10),
  1887. child: Icon(
  1888. IconData(
  1889. 0xe621,
  1890. fontFamily: 'iconfont',
  1891. ),
  1892. color: Constants.BlackTextColor,
  1893. size: 20,
  1894. ),
  1895. ),
  1896. onTap: () {
  1897. showModalBottomSheet(
  1898. context: registKey.currentContext,
  1899. builder: (BuildContext context) {
  1900. return SafeArea(
  1901. child: Container(
  1902. height: 137,
  1903. child: Column(
  1904. children: <Widget>[
  1905. InkWell(
  1906. onTap: () async {
  1907. Navigator.of(context).pop();
  1908. Navigator.of(context).push(
  1909. new MaterialPageRoute(
  1910. builder: (context) {
  1911. return AddFriendPage(
  1912. userId: userInfo.userId,
  1913. pageType:
  1914. SendMessagePageType.Remark,
  1915. originalName: Provider.of<
  1916. RefNameProvider>(
  1917. context)
  1918. .getRefName(userInfo.userId,
  1919. userInfo.nickName));
  1920. },
  1921. ),
  1922. );
  1923. },
  1924. child: Container(
  1925. alignment: Alignment.center,
  1926. height: 45,
  1927. child: Text(I18n.of(context).Remark,
  1928. textScaleFactor: 1.0,
  1929. style: TextStyle(
  1930. fontSize: 18,
  1931. color: Constants
  1932. .BlackTextColor)))),
  1933. Divider(height: 1),
  1934. InkWell(
  1935. child: Container(
  1936. height: 45,
  1937. alignment: Alignment.center,
  1938. child: Text(
  1939. isblack
  1940. ? I18n.of(context).remove_blacklist
  1941. : I18n.of(context).blacklist,
  1942. textScaleFactor: 1.0,
  1943. style: TextStyle(
  1944. fontSize: 18,
  1945. color: Constants.BlackTextColor),
  1946. ),
  1947. ),
  1948. onTap: isblack
  1949. ? () async {
  1950. HttpUtil().cancleBlackUser(
  1951. userInfo.userId, () {
  1952. Navigator.of(context).pop();
  1953. isblack = false;
  1954. });
  1955. }
  1956. : _buildConfirmBlack,
  1957. ),
  1958. Divider(height: 1),
  1959. InkWell(
  1960. onTap: () async {
  1961. Navigator.of(context).pop();
  1962. Navigator.of(context).push(
  1963. new MaterialPageRoute(
  1964. builder: (context) {
  1965. return InformUserPage(
  1966. isMan: isMan,
  1967. userId: userInfo.userId,
  1968. );
  1969. },
  1970. ),
  1971. );
  1972. },
  1973. child: Container(
  1974. alignment: Alignment.center,
  1975. height: 45,
  1976. child: Text(
  1977. I18n.of(context).anonymous_report,
  1978. textScaleFactor: 1.0,
  1979. style: TextStyle(
  1980. fontSize: 18,
  1981. color: Constants
  1982. .BlackTextColor)))),
  1983. ],
  1984. ),
  1985. ),
  1986. );
  1987. },
  1988. ).then((val) {});
  1989. },
  1990. ),
  1991. ),
  1992. ],
  1993. );
  1994. var bottomWidget = Container(
  1995. height: 55,
  1996. decoration: BoxDecoration(
  1997. border: Border(top: BorderSide(color: Color(0xffeaeaea))),
  1998. color: Constants.LightGreyBackgroundColor,
  1999. ),
  2000. child: Row(
  2001. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  2002. children: widget.addMode == 1 || widget.addMode == 3
  2003. ? <Widget>[_inviteFdBtn()]
  2004. : (widget.addMode == 2
  2005. ? [_dealInvite()]
  2006. : <Widget>[
  2007. _buildIcon(0xe68b, I18n.of(context).evaluate, true,
  2008. () async {
  2009. Map data = {
  2010. "userid": userInfo.userId,
  2011. 'evaluateuserid': UserData().basicInfo.userId,
  2012. };
  2013. data['sign'] = TokenMgr().getSign(data);
  2014. Response res = await HttpUtil().post('evaluate/user/info',
  2015. data: data, isShowLoading: true);
  2016. Map resData = res.data;
  2017. print(resData);
  2018. if (resData['code'] == 0) {
  2019. Navigator.of(context).push(TutorialOverlay(
  2020. child: ApplyContent(
  2021. userId: userInfo.userId,
  2022. isMan: isMan,
  2023. userInfo: resData['data'])));
  2024. } else {
  2025. showToast(resData['msg']);
  2026. }
  2027. }),
  2028. _buildIcon(
  2029. 0xe62f, I18n.of(context).chat, isCanWatch, onAudio)
  2030. ]),
  2031. ),
  2032. );
  2033. Widget content = Container(
  2034. color: Colors.white,
  2035. child: SafeArea(
  2036. child: Scaffold(
  2037. bottomNavigationBar: !isMyself ? bottomWidget : null,
  2038. appBar: appBar,
  2039. key: registKey,
  2040. body: SafeArea(
  2041. child: Container(
  2042. height: MediaQuery.of(context).size.height,
  2043. width: MediaQuery.of(context).size.width,
  2044. color: AppColors.BackgroundColor,
  2045. child: SingleChildScrollView(
  2046. child: _buildBody(),
  2047. ),
  2048. )))),
  2049. );
  2050. return CustomUI.buildPageLoading(context, content, !isLoadingFish);
  2051. }
  2052. //连麦
  2053. onAudio() async {
  2054. testChatPermission(() async {
  2055. if (userInfo.chatStatus == 0) {
  2056. showToast(I18n.of(context).cantt_voice);
  2057. return;
  2058. }
  2059. if (BlacklistMgr.isBlack(userInfo.userId)) {
  2060. return;
  2061. }
  2062. //对方关闭陌生人消息,则提示
  2063. if (!userInfo.isCanStrangerNews) {
  2064. showToast(I18n.of(context).stranger_close_tips);
  2065. return;
  2066. }
  2067. if (await CustomUI.showPermissionSetting(context,
  2068. PermissionGroup.microphone, I18n.of(context).video_permission)) {
  2069. AppNavigator.pushAudioChatPage(context, userInfo);
  2070. } else {
  2071. showToast(I18n.of(context).need_record);
  2072. }
  2073. });
  2074. }
  2075. }