Hibok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

574 lines
18 KiB

  1. import 'dart:io';
  2. import 'dart:typed_data';
  3. import 'package:chat/data/UserData.dart';
  4. import 'package:chat/data/constants.dart';
  5. import 'package:chat/generated/i18n.dart';
  6. import 'package:chat/home/rich_title.dart';
  7. import 'package:chat/models/UserInfo.dart';
  8. import 'package:chat/models/money_change.dart';
  9. import 'package:chat/models/ref_name_provider.dart';
  10. import 'package:chat/utils/ChargeMoney.dart';
  11. import 'package:chat/utils/CustomUI.dart';
  12. import 'package:chat/utils/HttpUtil.dart';
  13. import 'package:chat/utils/MessageMgr.dart';
  14. import 'package:chat/utils/PicSwiper.dart';
  15. import 'package:chat/utils/TokenMgr.dart';
  16. import 'package:chat/utils/file_cache_mgr.dart';
  17. import 'package:chat/utils/screen.dart';
  18. import 'package:dio/dio.dart';
  19. import 'package:flutter/cupertino.dart';
  20. import 'package:flutter/material.dart';
  21. import 'package:multi_image_picker/multi_image_picker.dart';
  22. import 'package:oktoast/oktoast.dart';
  23. import 'package:provider/provider.dart';
  24. import 'VerificationCenter.dart';
  25. import 'VipPage.dart';
  26. import 'money_picture_view.dart';
  27. const double LeftSize = 80;
  28. const MaxImgSize = 20;
  29. class PhotoPage extends StatefulWidget {
  30. @required
  31. final UserInfo userInfo;
  32. PhotoPage({Key key, this.userInfo}) : super(key: key);
  33. @override
  34. _PhotoPageState createState() => new _PhotoPageState();
  35. }
  36. class _PhotoPageState extends State<PhotoPage> {
  37. bool isMyself = false;
  38. bool isMan = false;
  39. Map imgList = {};
  40. bool isLoadingFinish = false;
  41. double imgWidth = (Screen.width - LeftSize - 60) / 3;
  42. var resultList = [];
  43. bool isBuyPicture = false;
  44. @override
  45. void initState() {
  46. super.initState();
  47. isMyself = widget.userInfo.userId == UserData().basicInfo.userId;
  48. isMan = widget.userInfo.sex == 1;
  49. isBuyPicture = (isMyself ||
  50. widget.userInfo.photoAut == 0 ||
  51. widget.userInfo.payStatus == 1);
  52. getImg();
  53. MessageMgr().on('refresh_photo', msgRefreshPhoto);
  54. }
  55. msgRefreshPhoto(data) {
  56. getImg();
  57. }
  58. void getImg() async {
  59. Map data = {
  60. "visitUserId": UserData().basicInfo.userId,
  61. "userId": widget.userInfo.userId,
  62. };
  63. data['sign'] = TokenMgr().getSign(data);
  64. Response res = await HttpUtil().post('user/personal/album', data: data);
  65. if (res == null) {
  66. return;
  67. }
  68. isLoadingFinish = true;
  69. Map resData = res.data;
  70. if (resData['code'] == 0) {
  71. imgList = {};
  72. resultList = resData['data'] ?? [];
  73. for (int i = 0; i < resultList.length; i++) {
  74. var temp = DateTime.parse(resultList[i]['CreatTime']);
  75. if (imgList[temp.year] == null) {
  76. imgList[temp.year] = {
  77. 1: [],
  78. 2: [],
  79. 3: [],
  80. 4: [],
  81. 5: [],
  82. 6: [],
  83. 7: [],
  84. 8: [],
  85. 9: [],
  86. 10: [],
  87. 11: [],
  88. 12: [],
  89. };
  90. }
  91. imgList[temp.year][temp.month].add(resultList[i]);
  92. }
  93. if (isMyself) {
  94. UserData().picNum = 0;
  95. for (int i = 0; i < resultList.length; i++) {
  96. if (resultList[i]['Status'] == 1) {
  97. UserData().picNum++;
  98. }
  99. if (resultList[i]['Status'] == 0 || resultList[i]['Status'] == 2) {
  100. UserData().haveReview = true;
  101. }
  102. }
  103. }
  104. if (mounted) {
  105. setState(() {});
  106. }
  107. }
  108. }
  109. @override
  110. Widget build(BuildContext context) {
  111. var content = Scaffold(
  112. appBar: AppBar(
  113. title: !isMyself
  114. ? Text(
  115. (isMyself
  116. ? I18n.of(context).my_album
  117. : (isMan
  118. ? I18n.of(context).his_photo
  119. : I18n.of(context).her_photo)),
  120. textScaleFactor: 1.0,
  121. style: TextStyle(
  122. color: AppColors.NewAppbarTextColor, fontSize: 20),
  123. )
  124. : Column(children: <Widget>[
  125. Text(
  126. (isMyself
  127. ? I18n.of(context).my_album
  128. : (isMan
  129. ? I18n.of(context).his_photo
  130. : I18n.of(context).her_photo)),
  131. textScaleFactor: 1.0,
  132. style: TextStyle(
  133. color: AppColors.NewAppbarTextColor, fontSize: 20),
  134. ),
  135. Text(
  136. '${resultList.length}/$MaxImgSize',
  137. style: TextStyle(fontSize: 11),
  138. )
  139. ]),
  140. leading: CustomUI.buildCustomLeading(context),
  141. titleSpacing: -10,
  142. centerTitle: true,
  143. elevation: 1,
  144. actions: <Widget>[
  145. !isMan && isMyself
  146. ? Container(
  147. alignment: Alignment.center,
  148. child: new InkWell(
  149. child: new Padding(
  150. padding: EdgeInsets.only(
  151. right: 15, left: 15, top: 10, bottom: 10),
  152. child: new Text(
  153. I18n.of(context).set_photo,
  154. textScaleFactor: 1.0,
  155. style: TextStyle(
  156. color: Constants.BlueTextColor, fontSize: 12),
  157. ),
  158. ),
  159. onTap: () {
  160. if (!widget.userInfo.isAttestation) {
  161. _buildNotTrue();
  162. return;
  163. }
  164. if (imgList.length == 0) {
  165. showToast(I18n.of(context).no_photos);
  166. return;
  167. }
  168. var moneyList = [];
  169. for (int i = 0; i < resultList.length; i++) {
  170. if (resultList[i]['Status'] == 1) {
  171. moneyList.add(resultList[i]);
  172. }
  173. }
  174. Navigator.of(context)
  175. .push(new MaterialPageRoute(builder: (context) {
  176. return MoneyPicture(
  177. imageList: moneyList,
  178. );
  179. }));
  180. },
  181. ),
  182. )
  183. : Container()
  184. ]),
  185. backgroundColor: Colors.white,
  186. body: SafeArea(
  187. child: SingleChildScrollView(
  188. child: Column(children: _buildBody()),
  189. )),
  190. );
  191. return CustomUI.buildPageLoading(context, content, !isLoadingFinish);
  192. }
  193. void _buildNotTrue() {
  194. CustomUI.buildOneConfirm(context, I18n.of(context).moneyPageTip,
  195. I18n.of(context).authenticate_now, () {
  196. Navigator.pop(context);
  197. Navigator.of(context).push(
  198. new MaterialPageRoute(
  199. builder: (context) {
  200. return VerificationCenterPage();
  201. },
  202. ),
  203. );
  204. });
  205. }
  206. buyPhoto() {
  207. //女性用户付费,男性用户会员的话免费解锁,非会员付费解锁
  208. becomeVip() {
  209. Navigator.of(context).push(
  210. new MaterialPageRoute(
  211. builder: (context) {
  212. return VipPage();
  213. },
  214. ),
  215. );
  216. }
  217. payCallback() {
  218. if (Provider.of<MoneyChangeProvider>(context).money <
  219. widget.userInfo.price) {
  220. Navigator.of(context).pop();
  221. CustomUI.buildOneConfirm(context, I18n.of(context).balance_insufficien,
  222. I18n.of(context).recharge, () {
  223. Navigator.of(context).pop();
  224. ChargeMoney.showChargeSheet(context, () {
  225. setState(() {});
  226. });
  227. });
  228. return;
  229. }
  230. Navigator.of(context).pop();
  231. HttpUtil().buyPictures(
  232. widget.userInfo.price, widget.userInfo.userId, context, () {
  233. setState(() {
  234. isBuyPicture = true;
  235. widget.userInfo.payStatus = 1;
  236. });
  237. });
  238. }
  239. freeTime() {
  240. HttpUtil().userFreeTime(context, widget.userInfo.userId, 1, () {
  241. UserData().basicInfo.usedNum++;
  242. Navigator.of(context).pop();
  243. setState(() {
  244. isBuyPicture = true;
  245. widget.userInfo.payStatus = 1;
  246. });
  247. });
  248. }
  249. String title = I18n.of(context).unlock_user.replaceFirst(
  250. '/s1',
  251. Provider.of<RefNameProvider>(context)
  252. .getRefName(widget.userInfo.userId, widget.userInfo.nickName),
  253. );
  254. if (!UserData().isMan()) {
  255. CustomUI.buildOneConfirm(
  256. context,
  257. title,
  258. I18n.of(context)
  259. .pay_unlock
  260. .replaceFirst('/s1', widget.userInfo.price.toString()),
  261. payCallback);
  262. } else if (UserData().isVip) {
  263. if (UserData().basicInfo.freeNum < UserData().basicInfo.usedNum) {
  264. CustomUI.buildOneConfirm(
  265. context,
  266. title,
  267. I18n.of(context)
  268. .pay_unlock
  269. .replaceFirst('/s1', widget.userInfo.price.toString()),
  270. payCallback);
  271. } else {
  272. CustomUI.buildOneConfirm(
  273. context, title, I18n.of(context).unlock_choose, freeTime);
  274. }
  275. } else {
  276. CustomUI.buildTowConfirm(
  277. context,
  278. title,
  279. I18n.of(context).become_member,
  280. becomeVip,
  281. I18n.of(context)
  282. .pay_unlock
  283. .replaceFirst('/s1', widget.userInfo.price.toString()),
  284. payCallback);
  285. }
  286. }
  287. Widget _buildLockWidget() {
  288. TitleItem title;
  289. if (!isMan) {
  290. title = UserData().isVip
  291. ? TitleItem(
  292. title: I18n.of(context).unlock_user,
  293. name: Provider.of<RefNameProvider>(context)
  294. .getRefName(widget.userInfo.userId, widget.userInfo.nickName),
  295. )
  296. : TitleItem(
  297. title: I18n.of(context).free_unlock,
  298. name: widget.userInfo.price.toString() +
  299. I18n.of(context).mask_coin);
  300. } else {
  301. title = TitleItem(
  302. title: I18n.of(context).pay_unlock,
  303. name: widget.userInfo.price.toString());
  304. }
  305. return Container(
  306. height: Screen.height * 0.7,
  307. alignment: Alignment.center,
  308. child: Column(
  309. mainAxisAlignment: MainAxisAlignment.center,
  310. children: <Widget>[
  311. Image.asset(
  312. 'assets/images/lock_photo.png',
  313. width: 160,
  314. //color: Colors.grey[700],
  315. ),
  316. Container(
  317. margin: EdgeInsets.only(top: 20),
  318. alignment: Alignment.center,
  319. child: Text(
  320. isMan ? I18n.of(context).set_lock : I18n.of(context).set_lock2,
  321. textScaleFactor: 1.0,
  322. style: TextStyle(
  323. color: Colors.grey[700],
  324. fontSize: 15,
  325. fontWeight: FontWeight.bold),
  326. ),
  327. ),
  328. Container(
  329. margin: EdgeInsets.only(top: 8),
  330. alignment: Alignment.center,
  331. child: RichText(
  332. text: TextSpan(
  333. children: RichTitle.getRichText(title,
  334. titleStyle:
  335. TextStyle(color: Colors.grey[700], fontSize: 13),
  336. nameStyle: TextStyle(color: Colors.red, fontSize: 13))),
  337. ),
  338. ),
  339. InkWell(
  340. onTap: buyPhoto,
  341. child: Container(
  342. margin: EdgeInsets.only(top: 30),
  343. padding: EdgeInsets.only(top: 6, bottom: 6),
  344. width: 100,
  345. alignment: Alignment.center,
  346. decoration: Constants.ConfirmBUttonBoxDecoration,
  347. child: Text(
  348. I18n.of(context).unlock,
  349. textScaleFactor: 1.0,
  350. style: TextStyle(color: Colors.white, fontSize: 18),
  351. ),
  352. )),
  353. ],
  354. ));
  355. }
  356. List<Widget> _buildBody() {
  357. List<Widget> list = [_buildUpload()];
  358. if (imgList.length == 0 && isLoadingFinish && !isMyself) {
  359. list.add(CustomUI.buildNoData(context));
  360. return list;
  361. }
  362. if (!isBuyPicture) {
  363. list.add(_buildLockWidget());
  364. return list;
  365. }
  366. imgList.keys.forEach((k) {
  367. list.add(_buildYear(k));
  368. });
  369. return list;
  370. }
  371. //上传相册
  372. void _uploadPhoto() async {
  373. int leftLength = MaxImgSize - imgList.length;
  374. if (leftLength <= 0) {
  375. showToast(I18n.of(context)
  376. .max_upload_size
  377. .replaceFirst('/s1', MaxImgSize.toString()));
  378. return;
  379. }
  380. List<Asset> resultList = List<Asset>();
  381. resultList = await MultiImagePicker.pickImages(
  382. maxImages: leftLength > 9 ? 9 : leftLength,
  383. enableCamera: false,
  384. selectedAssets: [],
  385. cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
  386. materialOptions: MaterialOptions(
  387. actionBarColor: "#50A7F9",
  388. actionBarTitle: "Hibok",
  389. allViewTitle: "",
  390. useDetailsView: true,
  391. selectCircleStrokeColor: "#000000",
  392. ),
  393. );
  394. if (resultList != null && resultList.length > 0) {
  395. List<File> fileList = [];
  396. for (var i = 0; i < resultList.length; i++) {
  397. Asset photoEntity = resultList[i];
  398. print('名字:${photoEntity.name}');
  399. ByteData byteData = await photoEntity.getByteData();
  400. File file = await FileCacheMgr().writeFile(
  401. 'temp-photo-${DateTime.now().millisecondsSinceEpoch}.png',
  402. byteData.buffer.asInt8List(0));
  403. fileList.add(file);
  404. }
  405. print('文件列表${fileList.length}');
  406. Map data = {"type": 2, "userId": UserData().basicInfo.userId};
  407. data['sign'] = TokenMgr().getSign(data);
  408. data['sex'] = UserData().basicInfo.sex;
  409. data['isBurn'] = 0;
  410. Response res = await HttpUtil().uploadFiles(
  411. fileList, data, 'upload/post/postfiles', 'image',
  412. isShowLoading: true);
  413. var resData = res.data;
  414. if (resData['code'] == 0) {
  415. if (resData['data']['msg'] != '' && resData['data']['msg'] != null) {
  416. showToast(resData['data']['msg']);
  417. }
  418. if (resData['msg'] == '' ||
  419. resData['msg'].split('|').length != fileList.length) {
  420. showToast(I18n.of(context).hava_error_photo);
  421. }
  422. getImg();
  423. } else {
  424. showToast(resData['msg']);
  425. }
  426. }
  427. }
  428. Widget _buildUpload() {
  429. return isMyself
  430. ? Container(
  431. margin: EdgeInsets.only(top: 20),
  432. child: Row(
  433. crossAxisAlignment: CrossAxisAlignment.start,
  434. children: <Widget>[
  435. Container(
  436. alignment: Alignment.centerRight,
  437. margin: EdgeInsets.only(right: 15),
  438. width: LeftSize,
  439. child: Text(
  440. I18n.of(context).upload1,
  441. style:
  442. TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
  443. )),
  444. InkWell(
  445. onTap: _uploadPhoto,
  446. child: Container(
  447. width: imgWidth,
  448. height: imgWidth,
  449. margin: EdgeInsets.all(5),
  450. decoration: BoxDecoration(
  451. color: Color(0xFFEDEDED),
  452. borderRadius: BorderRadius.circular(10)),
  453. child: Icon(
  454. IconData(0xe686, fontFamily: Constants.IconFontFamily),
  455. size: 35,
  456. color: Colors.white,
  457. ),
  458. ))
  459. ],
  460. ),
  461. )
  462. : Container();
  463. }
  464. Widget _buildYear(int year) {
  465. var list = [_buildYearTips(year)];
  466. imgList[year].keys.forEach((k) {
  467. if (imgList[year][k].length > 0) {
  468. list.add(_buildMonth(year, k));
  469. }
  470. });
  471. return Container(
  472. width: Screen.width,
  473. child: Column(
  474. crossAxisAlignment: CrossAxisAlignment.start,
  475. children: list,
  476. ));
  477. }
  478. Widget _buildYearTips(int year) {
  479. return Container(
  480. alignment: Alignment.centerRight,
  481. margin: EdgeInsets.only(right: 15, top: 20, bottom: 18),
  482. width: LeftSize,
  483. child: Text(
  484. '$year${I18n.of(context).year}',
  485. style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
  486. ));
  487. }
  488. Widget _buildMonth(int year, int month) {
  489. if (imgList[year] == null || imgList[year][month] == null) {
  490. return Container();
  491. }
  492. List<PicSwiperItem> pisc = [];
  493. imgList[year][month].forEach((f) {
  494. pisc.add(PicSwiperItem(
  495. f['ImgUrl'],
  496. id: f['Id'],
  497. type: f['Type'],
  498. isWatch: f['IsCheck'] == 1,
  499. userId: widget.userInfo.userId,
  500. isBuy: f['PayStatus'] == 1,
  501. isCheck: f['Status'] == 0,
  502. ));
  503. });
  504. List<Widget> list = [];
  505. imgList[year][month].forEach((data) {
  506. bool isWatch = data['IsCheck'] == 1;
  507. double raduis = 10;
  508. list.add(CustomUI.buildImgCover(data['Id'], pisc, data['ImgUrl'],
  509. imgWidth, raduis, isWatch, context, data['Type'],
  510. isMyself: isMyself,
  511. payStatus: data['PayStatus'],
  512. state: isMan ? 1 : data['Status']));
  513. });
  514. return Row(
  515. crossAxisAlignment: CrossAxisAlignment.start,
  516. children: <Widget>[
  517. Container(
  518. alignment: Alignment.centerRight,
  519. margin: EdgeInsets.only(right: 15, top: 1),
  520. width: LeftSize,
  521. child: Text(
  522. '$month${I18n.of(context).month}',
  523. style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
  524. )),
  525. Container(
  526. width: Screen.width - LeftSize - 15,
  527. child: Wrap(
  528. crossAxisAlignment: WrapCrossAlignment.start,
  529. children: list,
  530. ))
  531. ],
  532. );
  533. }
  534. @override
  535. void dispose() {
  536. super.dispose();
  537. MessageMgr().off('refresh_photo', msgRefreshPhoto);
  538. }
  539. }