Hibok
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

405 行
13 KiB

  1. import 'dart:io';
  2. import 'package:chat/data/WebData.dart';
  3. import 'package:chat/data/constants.dart';
  4. import 'package:chat/generated/i18n.dart';
  5. import 'package:chat/utils/CustomUI.dart';
  6. import 'package:chat/utils/LoadingDialog.dart';
  7. import 'package:chat/utils/sp_utils.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:image_picker/image_picker.dart';
  10. import 'package:oktoast/oktoast.dart';
  11. import 'package:video_player/video_player.dart';
  12. import '../data/UserData.dart';
  13. import '../utils/TokenMgr.dart';
  14. import "package:dio/dio.dart";
  15. import '../utils/HttpUtil.dart';
  16. import '../utils/ShadowButton.dart';
  17. var cardWidth;
  18. class VerificationCenterPage extends StatefulWidget {
  19. VerificationCenterPage({Key key}) : super(key: key);
  20. _VerificationCenterPageState createState() => _VerificationCenterPageState();
  21. }
  22. class _VerificationCenterPageState extends State<VerificationCenterPage> {
  23. String code = '';
  24. String videoUrl = '';
  25. String buttonStr = '';
  26. File videoFile;
  27. int state = 3;
  28. bool isPostVideo = false;
  29. bool isShowPlayButton = true;
  30. VideoPlayerController _controller;
  31. static const Separate_Size = 17.0;
  32. bool isLoadingFish = false;
  33. bool isLoadingVideoFinish = false;
  34. @override
  35. void initState() {
  36. super.initState();
  37. getInfo();
  38. }
  39. @override
  40. void dispose() {
  41. if (_controller != null) {
  42. _controller.dispose();
  43. }
  44. super.dispose();
  45. }
  46. getInfo() async {
  47. Map data = {
  48. "userId": UserData().basicInfo.userId,
  49. };
  50. data['sign'] = TokenMgr().getSign(data);
  51. // 0=审核中,1=申请成功,2=申请失败,3未申请
  52. Response res = await HttpUtil().post('user/female/authInfo',
  53. data: data, failback: () => Navigator.of(context).pop());
  54. Map resData = res.data;
  55. if (resData['code'] == 0) {
  56. code = resData['data']['Code'];
  57. state = resData['data']['Status'];
  58. if (state == 0 || state == 1) {
  59. isPostVideo = true;
  60. videoUrl = resData['data']['AttestationValue'];
  61. var path = await UserData().getLoaclVideoPath(videoUrl);
  62. _controller = VideoPlayerController.file(new File(path))
  63. ..initialize().then((_) {
  64. setState(() {
  65. isLoadingVideoFinish = true;
  66. });
  67. });
  68. _controller.addListener(() {
  69. if (_controller.value.position >= _controller.value.duration) {
  70. isShowPlayButton = true;
  71. setState(() {});
  72. }
  73. });
  74. buttonStr = I18n.of(context).under_review;
  75. }
  76. isLoadingFish = true;
  77. setState(() {});
  78. }
  79. }
  80. @override
  81. Widget build(BuildContext context) {
  82. Size screenSize = MediaQuery.of(context).size;
  83. cardWidth = screenSize.width;
  84. Widget content = Scaffold(
  85. appBar: AppBar(
  86. backgroundColor: AppColors.NewAppbarBgColor,
  87. title: Text(
  88. I18n.of(context).certification_center,
  89. style: TextStyle(color: AppColors.NewAppbarTextColor),
  90. ),
  91. centerTitle: true,
  92. leading: CustomUI.buildCustomLeading(context),
  93. elevation: 0,
  94. ),
  95. body: SafeArea(
  96. child: Container(
  97. padding: EdgeInsets.symmetric(horizontal: 10),
  98. color: const Color(0xFFF4F4F4),
  99. height: MediaQuery.of(context).size.height,
  100. child: SingleChildScrollView(
  101. child: _buildBody(),
  102. ))));
  103. return CustomUI.buildPageLoading(context, content, !isLoadingFish);
  104. }
  105. BoxDecoration getCardDecoration() {
  106. return new BoxDecoration(
  107. color: Colors.white,
  108. boxShadow: [
  109. BoxShadow(
  110. color: Color.fromRGBO(230, 230, 230, 1),
  111. offset: Offset(0, 10),
  112. blurRadius: 8,
  113. )
  114. ],
  115. borderRadius: BorderRadius.all(Radius.circular(10)));
  116. }
  117. Widget _buildBody() {
  118. return Column(
  119. children: <Widget>[
  120. _buildVideo(),
  121. _buildTip1(),
  122. SizedBox(height: Separate_Size),
  123. _buildTip2(),
  124. SizedBox(height: Separate_Size),
  125. _buildTip3(),
  126. SizedBox(height: Separate_Size),
  127. _buildRegisterButton(),
  128. Container(
  129. margin: EdgeInsets.only(top: 10.5, bottom: Separate_Size),
  130. child: Text(
  131. I18n.of(context).after_authentication,
  132. style: TextStyle(fontSize: 12, color: Constants.GreyTextColor),
  133. ),
  134. ),
  135. ],
  136. );
  137. }
  138. Widget _buildVideo() {
  139. Widget stack = Stack(
  140. children: <Widget>[
  141. Container(
  142. height: 230,
  143. alignment: Alignment.center,
  144. child: _controller != null && _controller.value.initialized
  145. ? AspectRatio(
  146. aspectRatio: _controller.value.aspectRatio,
  147. child: VideoPlayer(_controller),
  148. )
  149. : Container(),
  150. ),
  151. InkWell(
  152. highlightColor: Colors.transparent,
  153. radius: 0,
  154. onTap: () {
  155. setState(() {
  156. if (!_controller.value.isPlaying) {
  157. _controller.seekTo(Duration());
  158. _controller.play();
  159. isShowPlayButton = false;
  160. setState(() {});
  161. }
  162. });
  163. },
  164. child: Container(
  165. height: 230,
  166. alignment: Alignment.center,
  167. child: !isLoadingVideoFinish
  168. ? CircularProgressIndicator(
  169. valueColor: AlwaysStoppedAnimation(Colors.black38))
  170. : Container(
  171. color: Colors.black38,
  172. child: Icon(
  173. Icons.play_arrow,
  174. size:
  175. _controller != null && _controller.value.isPlaying
  176. ? 0
  177. : 50,
  178. color: Colors.white,
  179. ),
  180. )))
  181. ],
  182. );
  183. Widget img = Container(
  184. child: Image.asset(
  185. 'assets/images/login/rzzx.png',
  186. height: 230,
  187. ),
  188. );
  189. return (videoUrl == '') ? img : stack;
  190. }
  191. Widget _buildTip1() {
  192. return Container(
  193. alignment: Alignment.center,
  194. padding: EdgeInsets.only(top: 15, left: 20, right: 20, bottom: 15),
  195. width: cardWidth,
  196. child: Column(
  197. children: <Widget>[
  198. Container(
  199. padding: EdgeInsets.only(bottom: 10),
  200. alignment: Alignment.centerLeft,
  201. child: Text(
  202. I18n.of(context).certification_conditions,
  203. textScaleFactor: 1.0,
  204. style: TextStyle(
  205. fontSize: 16,
  206. fontWeight: FontWeight.w600,
  207. color: Constants.BlackTextColor),
  208. )),
  209. Container(
  210. padding: EdgeInsets.only(bottom: 5),
  211. alignment: Alignment.centerLeft,
  212. child: Text(I18n.of(context).conditions1, textScaleFactor: 1.0)),
  213. Align(
  214. alignment: Alignment.centerLeft,
  215. child: Text(I18n.of(context).conditions2, textScaleFactor: 1.0)),
  216. ],
  217. ),
  218. decoration: getCardDecoration(),
  219. );
  220. }
  221. Widget _buildTip2() {
  222. return Container(
  223. alignment: Alignment.center,
  224. padding: EdgeInsets.only(top: 15, left: 20, right: 20, bottom: 15),
  225. width: cardWidth,
  226. child: Column(
  227. children: <Widget>[
  228. Container(
  229. padding: EdgeInsets.only(bottom: 10),
  230. alignment: Alignment.centerLeft,
  231. child: Text(
  232. I18n.of(context).verification_method,
  233. textScaleFactor: 1.0,
  234. style: TextStyle(
  235. fontSize: 16,
  236. fontWeight: FontWeight.w600,
  237. color: Constants.BlackTextColor),
  238. )),
  239. Container(
  240. alignment: Alignment.centerLeft,
  241. child: Text(I18n.of(context).method3, textScaleFactor: 1.0)),
  242. Container(
  243. padding: EdgeInsets.only(bottom: 10, top: 10),
  244. alignment: Alignment.center,
  245. child: Text(
  246. code,
  247. textScaleFactor: 1.0,
  248. style: TextStyle(
  249. fontSize: 30,
  250. fontWeight: FontWeight.w600,
  251. color: const Color(0xFFFF4523)),
  252. )),
  253. Align(
  254. alignment: Alignment.centerLeft,
  255. child: Text(I18n.of(context).method4, textScaleFactor: 1.0)),
  256. ],
  257. ),
  258. decoration: getCardDecoration(),
  259. );
  260. }
  261. Widget _buildTip3() {
  262. var str = '';
  263. if (state == 0) {
  264. str = I18n.of(context).certificating;
  265. } else if (state == 2) {
  266. str = I18n.of(context).re_upload2;
  267. } else {
  268. str = I18n.of(context).not_authenticate;
  269. }
  270. return Container(
  271. alignment: Alignment.center,
  272. padding: EdgeInsets.only(top: 15, left: 20, right: 20, bottom: 15),
  273. width: cardWidth,
  274. child: Column(
  275. children: <Widget>[
  276. Container(
  277. padding: EdgeInsets.only(bottom: 10),
  278. alignment: Alignment.centerLeft,
  279. child: Text(
  280. I18n.of(context).certification_status,
  281. textScaleFactor: 1.0,
  282. style: TextStyle(
  283. fontSize: 16,
  284. fontWeight: FontWeight.w600,
  285. color: Constants.BlackTextColor),
  286. )),
  287. Container(
  288. padding: EdgeInsets.only(bottom: 5),
  289. alignment: Alignment.centerLeft,
  290. child: Text(str, textScaleFactor: 1.0)),
  291. ],
  292. ),
  293. decoration: getCardDecoration(),
  294. );
  295. }
  296. void _sendVideo() async {
  297. showDialog(
  298. context: context,
  299. barrierDismissible: false,
  300. builder: (BuildContext context) {
  301. return LoadingDialog(
  302. text: "",
  303. );
  304. });
  305. videoFile = await ImagePicker.pickVideo(source: ImageSource.camera);
  306. Navigator.of(context).pop();
  307. if (videoFile != null) {
  308. var size = await videoFile.length();
  309. if (size > 104857600) {
  310. showToast(I18n.of(context).video_more_big);
  311. videoFile = null;
  312. return;
  313. }
  314. Map data = {"type": 5, "userId": UserData().basicInfo.userId};
  315. data['sign'] = TokenMgr().getSign(data);
  316. Response res = await HttpUtil().uploadFile(
  317. videoFile, data, 'upload/file/postflie', 'video',
  318. isShowLoading: true);
  319. var resData = res.data;
  320. if (resData['code'] == 0) {
  321. SPUtils.saveString(
  322. Constants.LocalCertifiedvideo +
  323. UserData().basicInfo.userId.toString(),
  324. videoFile.path);
  325. showToast(I18n.of(context).success);
  326. videoUrl = resData['msg'];
  327. isPostVideo = true;
  328. isLoadingVideoFinish = true;
  329. _controller = VideoPlayerController.file(videoFile)
  330. ..initialize().then((_) {
  331. // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
  332. setState(() {});
  333. });
  334. _controller.addListener(() {
  335. if (_controller.value.position >= _controller.value.duration) {
  336. isShowPlayButton = true;
  337. setState(() {});
  338. }
  339. });
  340. buttonStr = I18n.of(context).submit;
  341. setState(() {});
  342. }
  343. }
  344. }
  345. void postInfo() async {
  346. Map data = {
  347. "userId": UserData().basicInfo.userId,
  348. "videoUrl": WebData().deleteDemain(videoUrl),
  349. };
  350. data['sign'] = TokenMgr().getSign(data);
  351. Response res = await HttpUtil().post('user/auth/video', data: data);
  352. Map resData = res.data;
  353. if (resData['code'] == 0) {
  354. showToast(resData['msg']);
  355. state = 0;
  356. buttonStr = I18n.of(context).under_review;
  357. setState(() {});
  358. }
  359. }
  360. //构建注册按钮
  361. Widget _buildRegisterButton() {
  362. Text text = new Text(
  363. buttonStr == '' ? I18n.of(context).upload_video : buttonStr,
  364. textScaleFactor: 1.0,
  365. style: TextStyle(fontSize: 15, color: Colors.white));
  366. LinearGradient gradientColor = new LinearGradient(colors: <Color>[
  367. Constants.ConfrimButtonColor,
  368. Constants.ConfrimButtonColor,
  369. ]);
  370. return new Container(
  371. margin: EdgeInsets.only(top: 5.5),
  372. height: 44,
  373. width: MediaQuery.of(context).size.width * 0.86,
  374. child: ShadowButton().builder(gradientColor, text,
  375. state == 0 ? () {} : (videoUrl == '' ? _sendVideo : postInfo)),
  376. );
  377. }
  378. }