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.
 
 
 
 
 
 

488 regels
15 KiB

  1. import 'dart:io';
  2. import 'dart:typed_data';
  3. import 'package:cached_network_image/cached_network_image.dart';
  4. import 'package:chat/data/UserData.dart';
  5. import 'package:chat/data/WebData.dart';
  6. import 'package:chat/data/constants.dart';
  7. import 'package:chat/generated/i18n.dart';
  8. import 'package:chat/photo/entity/options.dart';
  9. import 'package:chat/photo/photo.dart';
  10. import 'package:chat/utils/CustomUI.dart';
  11. import 'package:chat/utils/HttpUtil.dart';
  12. import 'package:chat/utils/PicSwiper.dart';
  13. import 'package:chat/utils/file_cache_mgr.dart';
  14. import 'package:chat/utils/screen.dart';
  15. import 'package:dio/dio.dart';
  16. import 'package:flutter/material.dart';
  17. import 'package:multi_image_picker/multi_image_picker.dart';
  18. import 'package:oktoast/oktoast.dart';
  19. import 'package:photo_manager/photo_manager.dart';
  20. import '../data/UserData.dart';
  21. import '../utils/TokenMgr.dart';
  22. enum reason {
  23. advertising,
  24. rail,
  25. breakAppointment,
  26. sex,
  27. liar,
  28. }
  29. const int MaxImgNum = 4;
  30. class InformUserPage extends StatefulWidget {
  31. @required
  32. final userId;
  33. final programId;
  34. final isProgram;
  35. @required
  36. final bool isMan;
  37. InformUserPage(
  38. {Key key,
  39. this.userId,
  40. this.programId,
  41. this.isMan = false,
  42. this.isProgram = false})
  43. : super(key: key);
  44. _InformUserPageState createState() => _InformUserPageState();
  45. }
  46. class _InformUserPageState extends State<InformUserPage> {
  47. int _socialType = 0;
  48. bool parkHidden = false;
  49. bool distanceHidden = false;
  50. bool msgHidden = false;
  51. String explain = '';
  52. //List imgFileList = [];
  53. //上传图片地址
  54. List<String> imgUrlList = [];
  55. BoxDecoration _getCardDecoration() {
  56. return new BoxDecoration(color: Colors.white);
  57. }
  58. @override
  59. void initState() {
  60. super.initState();
  61. print('InformUserPage initState');
  62. }
  63. @override
  64. Widget build(BuildContext context) {
  65. Widget appBar = new AppBar(
  66. title: Text(
  67. I18n.of(context).anonymous_report,
  68. textScaleFactor: 1.0,
  69. ),
  70. leading: CustomUI.buildCustomLeading(context),
  71. centerTitle: true,
  72. actions: <Widget>[
  73. new Container(
  74. alignment: Alignment.center,
  75. child: new InkWell(
  76. child: new Padding(
  77. padding:
  78. EdgeInsets.only(right: 15, left: 15, top: 10, bottom: 10),
  79. child: new Text(I18n.of(context).submit,
  80. textScaleFactor: 1.0, style: Constants.AppBarActionTextStyle),
  81. ),
  82. onTap: () async {
  83. if (imgUrlList == null || imgUrlList.length == 0) {
  84. showToast(I18n.of(context).bad_evaluate);
  85. return;
  86. }
  87. var data = {
  88. "reportuserId": UserData().basicInfo.userId,
  89. "userid": widget.userId,
  90. };
  91. data['sign'] = TokenMgr().getSign(data);
  92. data['type'] =
  93. widget.programId == null ? 1 : (widget.isProgram ? 2 : 3);
  94. data['objectId'] =
  95. widget.programId == null ? 0 : widget.programId;
  96. data['reason'] = _socialType + 1;
  97. String temp = "";
  98. imgUrlList.forEach((str) {
  99. temp += (temp == ""
  100. ? WebData().deleteDemain(str)
  101. : '|${WebData().deleteDemain(str)}');
  102. });
  103. data["imgurl"] = temp;
  104. data["explain"] = explain;
  105. Response res = await HttpUtil()
  106. .post('report/user/insert', data: data, isShowLoading: true);
  107. Map resData = res.data;
  108. if (resData['code'] == 0) {
  109. CustomUI.buildOneConfirm(context,
  110. I18n.of(context).waiting_results, I18n.of(context).ok, () {
  111. Navigator.of(context).pop();
  112. Navigator.of(context).pop();
  113. }, failcallbak: () {
  114. Navigator.of(context).pop();
  115. });
  116. } else {
  117. showToast(resData['msg']);
  118. }
  119. },
  120. ),
  121. )
  122. ],
  123. );
  124. return Scaffold(
  125. body: SafeArea(
  126. child: Center(
  127. child: Container(
  128. height: MediaQuery.of(context).size.height,
  129. width: MediaQuery.of(context).size.width,
  130. child: _buildBody(),
  131. ),
  132. )),
  133. appBar: appBar,
  134. );
  135. }
  136. Widget _buildBody() {
  137. return new ListView(
  138. children: <Widget>[
  139. _userDetail(),
  140. _buildMoreInfo(),
  141. _buildTips(),
  142. ],
  143. );
  144. }
  145. Widget _buildTips() {
  146. return Container(
  147. margin: EdgeInsets.only(top: 5, left: 30, right: 30),
  148. child: Text(
  149. I18n.of(context).if_something,
  150. textScaleFactor: 1.0,
  151. style: TextStyle(fontSize: 12, color: Colors.grey[700]),
  152. textAlign: TextAlign.center,
  153. ),
  154. );
  155. }
  156. //下划线
  157. Widget _buildDivider() {
  158. return new Container(
  159. margin: EdgeInsets.zero,
  160. padding: EdgeInsets.zero,
  161. height: 1,
  162. width: MediaQuery.of(context).size.width,
  163. child: new Divider(
  164. color: Colors.grey[300],
  165. ),
  166. );
  167. }
  168. void _sendPicture() async {
  169. List<Asset> resultList = List<Asset>();
  170. resultList = await MultiImagePicker.pickImages(
  171. maxImages: MaxImgNum - imgUrlList.length,
  172. enableCamera: false,
  173. selectedAssets: [],
  174. cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
  175. materialOptions: MaterialOptions(
  176. actionBarColor: "#50A7F9",
  177. actionBarTitle: "Hibok",
  178. allViewTitle: "",
  179. useDetailsView: false,
  180. selectCircleStrokeColor: "#000000",
  181. ),
  182. );
  183. if (resultList != null && resultList.length > 0) {
  184. List<File> fileList = [];
  185. for (var i = 0; i < resultList.length; i++) {
  186. Asset photoEntity = resultList[i];
  187. ByteData byteData = await photoEntity.getByteData();
  188. File file = await FileCacheMgr().writeFile('temp-photo-${DateTime.now().millisecondsSinceEpoch}-$i', byteData.buffer.asInt8List(0));
  189. fileList.add(file);
  190. }
  191. Map data = {"type": 3, "userId": UserData().basicInfo.userId};
  192. data['sign'] = TokenMgr().getSign(data);
  193. Response res = await HttpUtil().uploadFiles(
  194. fileList, data, 'upload/post/postfiles', 'image',
  195. isShowLoading: true);
  196. var resData = res.data;
  197. if (resData['code'] == 0 && resData['msg'] != null) {
  198. imgUrlList.addAll(resData['msg'].split("|"));
  199. setState(() {});
  200. }
  201. }
  202. // var photos = await PhotoPicker.pickAsset(
  203. // context: context,
  204. // themeColor: Color(0xFFF0F0F0),
  205. // maxSelected: MaxImgNum - imgUrlList.length,
  206. // textColor: Color(0xFF3F3F3F),
  207. // pickType: PickType.onlyImage);
  208. //
  209. // if (photos != null && photos.length > 0) {
  210. // List<File> fileList = [];
  211. // for (var i = 0; i < photos.length; i++) {
  212. // AssetEntity photoEntity = photos[i];
  213. // fileList.add(await photoEntity.file);
  214. // }
  215. // Map data = {"type": 3, "userId": UserData().basicInfo.userId};
  216. // data['sign'] = TokenMgr().getSign(data);
  217. // Response res = await HttpUtil().uploadFiles(
  218. // fileList, data, 'upload/post/postfiles', 'image',
  219. // isShowLoading: true);
  220. // var resData = res.data;
  221. // if (resData['code'] == 0 && resData['msg'] != null) {
  222. // imgUrlList.addAll(resData['msg'].split("|"));
  223. // setState(() {});
  224. // }
  225. // }
  226. }
  227. Widget _buildRadioButtom(str, radio, callback) {
  228. Widget left = Text(
  229. str,
  230. textScaleFactor: 1.0,
  231. style: TextStyle(fontSize: 14),
  232. );
  233. Widget right = new Expanded(
  234. child: new Align(
  235. alignment: Alignment.centerRight,
  236. child: radio,
  237. ));
  238. return InkWell(
  239. onTap: () {
  240. callback();
  241. },
  242. child: Container(
  243. padding: EdgeInsets.only(left: 15),
  244. child: new Row(
  245. children: <Widget>[left, right],
  246. ),
  247. ),
  248. );
  249. }
  250. //个人详情
  251. Widget _userDetail() {
  252. Widget tip =
  253. CustomUI.buildTopTip(15, I18n.of(context).report_reason, fontSize: 16);
  254. Widget radio1 = new Radio(
  255. value: reason.advertising.index,
  256. groupValue: _socialType, //当value和groupValue一致的时候则选中
  257. onChanged: (T) {
  258. setState(() {
  259. _socialType = T;
  260. });
  261. });
  262. Widget radio2 = new Radio(
  263. value: reason.rail.index,
  264. groupValue: _socialType, //当value和groupValue一致的时候则选中
  265. onChanged: (T) {
  266. setState(() {
  267. _socialType = T;
  268. });
  269. });
  270. Widget radio3 = new Radio(
  271. value: reason.breakAppointment.index,
  272. groupValue: _socialType, //当value和groupValue一致的时候则选中
  273. onChanged: (T) {
  274. setState(() {
  275. _socialType = T;
  276. });
  277. });
  278. Widget radio4 = new Radio(
  279. value: reason.sex.index,
  280. groupValue: _socialType, //当value和groupValue一致的时候则选中
  281. onChanged: (T) {
  282. setState(() {
  283. _socialType = T;
  284. });
  285. });
  286. Widget radio5 = new Radio(
  287. value: reason.liar.index,
  288. groupValue: _socialType, //当value和groupValue一致的时候则选中
  289. onChanged: (T) {
  290. setState(() {
  291. _socialType = T;
  292. });
  293. });
  294. List<Widget> basicList = [
  295. _buildRadioButtom(I18n.of(context).advertise, radio1, () {
  296. setState(() {
  297. _socialType = reason.advertising.index;
  298. });
  299. }),
  300. _buildDivider(),
  301. _buildRadioButtom(I18n.of(context).harassment, radio2, () {
  302. setState(() {
  303. _socialType = reason.rail.index;
  304. });
  305. }),
  306. _buildDivider(),
  307. _buildRadioButtom(I18n.of(context).false_photo, radio3, () {
  308. setState(() {
  309. _socialType = reason.breakAppointment.index;
  310. });
  311. }),
  312. _buildDivider(),
  313. _buildRadioButtom(I18n.of(context).erotic_vulgarity, radio4, () {
  314. setState(() {
  315. _socialType = reason.sex.index;
  316. });
  317. }),
  318. _buildDivider(),
  319. _buildRadioButtom(
  320. widget.isMan ? I18n.of(context).he_liar : I18n.of(context).she_liar,
  321. radio5, () {
  322. setState(() {
  323. _socialType = reason.liar.index;
  324. });
  325. }),
  326. ];
  327. var socialCard = new Container(
  328. decoration: _getCardDecoration(),
  329. width: MediaQuery.of(context).size.width,
  330. child: new Column(
  331. children: basicList,
  332. ),
  333. );
  334. return new Column(
  335. children: <Widget>[tip, socialCard],
  336. );
  337. }
  338. Widget _buildMoreInfo() {
  339. Widget tip = CustomUI.buildTopTip(15, I18n.of(context).provide_screenshots,
  340. fontSize: 15);
  341. Widget upButton = Container(
  342. child: InkWell(
  343. onTap: _sendPicture,
  344. child: Container(
  345. margin: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
  346. decoration: BoxDecoration(
  347. borderRadius: BorderRadius.circular(10.0),
  348. border: Border.all(color: Colors.grey)),
  349. width: 75,
  350. height: 75,
  351. child: ClipRRect(
  352. borderRadius: BorderRadius.circular(10),
  353. child: Icon(
  354. IconData(
  355. 0xe616,
  356. fontFamily: 'iconfont',
  357. ),
  358. color: Colors.grey,
  359. ),
  360. ))));
  361. List<Widget> list = imgUrlList.map((f) {
  362. return _buildImg(f);
  363. }).toList();
  364. if (list.length < MaxImgNum) {
  365. list.add(upButton);
  366. }
  367. var socialCard = new Container(
  368. width: MediaQuery.of(context).size.width,
  369. decoration: _getCardDecoration(),
  370. padding: EdgeInsets.only(bottom: 10),
  371. child: Column(
  372. crossAxisAlignment: CrossAxisAlignment.start,
  373. children: <Widget>[
  374. Padding(
  375. padding: EdgeInsets.only(left: 10, top: 10, bottom: 10),
  376. child: Wrap(
  377. crossAxisAlignment: WrapCrossAlignment.start,
  378. children: list)),
  379. _buildDivider(),
  380. Container(
  381. margin: EdgeInsets.only(top: 10, left: 14),
  382. child: fixedText(I18n.of(context).describe_details)),
  383. Container(
  384. padding: EdgeInsets.only(top: 2, left: 8, right: 14),
  385. child: TextField(
  386. keyboardAppearance: Brightness.light,
  387. style: TextStyle(textBaseline: TextBaseline.alphabetic),
  388. decoration: new InputDecoration(
  389. hintText: I18n.of(context).optional,
  390. hintStyle: TextStyle(fontSize: 14),
  391. border: InputBorder.none,
  392. ),
  393. maxLines: 5,
  394. maxLength: 200,
  395. onChanged: (str) {
  396. explain = str;
  397. },
  398. ),
  399. ),
  400. ],
  401. ),
  402. );
  403. return new Column(
  404. children: <Widget>[tip, socialCard],
  405. );
  406. }
  407. Widget _buildImg(f) {
  408. return Stack(
  409. children: <Widget>[
  410. InkWell(
  411. onTap: () {
  412. Navigator.of(context).push(
  413. new MaterialPageRoute(
  414. builder: (context) {
  415. return PicSwiper(
  416. id: imgUrlList.indexOf(f),
  417. pics: imgUrlList
  418. .map((f) => PicSwiperItem(
  419. f,
  420. id: imgUrlList.indexOf(f),
  421. ))
  422. .toList(),
  423. );
  424. },
  425. ),
  426. );
  427. },
  428. child: Container(
  429. height: 75,
  430. width: 75,
  431. margin: EdgeInsets.only(left: 5, right: 5, top: 5, bottom: 5),
  432. decoration:
  433. BoxDecoration(borderRadius: BorderRadius.circular(2.0)),
  434. child: ClipRRect(
  435. borderRadius: BorderRadius.circular(10),
  436. child: f == null
  437. ? Container()
  438. : CachedNetworkImage(
  439. imageUrl: f,
  440. fit: BoxFit.cover,
  441. ),
  442. ))),
  443. Positioned(
  444. right: 0,
  445. child: InkWell(
  446. onTap: () {
  447. imgUrlList.remove(f);
  448. setState(() {});
  449. },
  450. child: Image.asset(
  451. 'assets/images/login/delete.png',
  452. height: 20,
  453. )),
  454. )
  455. ],
  456. );
  457. }
  458. }