repair_submit_page.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  6. import 'package:image_picker/image_picker.dart';
  7. import 'package:keyboard_actions/keyboard_actions.dart';
  8. import 'package:liftmanager/internal/maintenance/maintenance_router.dart';
  9. import 'package:liftmanager/internal/repair/model/repair_fault_entity.dart';
  10. import 'package:liftmanager/internal/repair/model/repair_list_entity.dart';
  11. import 'package:liftmanager/internal/repair/repair_router.dart';
  12. import 'package:liftmanager/net/api_service.dart';
  13. import 'package:liftmanager/res/resources.dart';
  14. import 'package:liftmanager/routers/fluro_navigator.dart';
  15. import 'package:liftmanager/utils/image_utils.dart';
  16. import 'package:liftmanager/utils/theme_utils.dart';
  17. import 'package:liftmanager/utils/toast.dart';
  18. import 'package:liftmanager/widgets/app_bar.dart';
  19. import 'package:liftmanager/widgets/click_item.dart';
  20. import 'package:liftmanager/widgets/load_image.dart';
  21. import 'package:liftmanager/widgets/selected_image.dart';
  22. import 'dart:convert' as convert;
  23. class RepairSubmitPage extends StatefulWidget {
  24. RepairSubmitPage(this.item);
  25. final RepairItem item;
  26. @override
  27. State<StatefulWidget> createState() {
  28. return RepairSubmitPageState();
  29. }
  30. }
  31. class RepairSubmitPageState extends State<RepairSubmitPage> {
  32. List<File> images = [];
  33. List<RepairFaultEntity> repairList = [];
  34. TextEditingController _controller = TextEditingController();
  35. String faultPart = "";
  36. String faultPartID = "";
  37. String faultReason = "";
  38. String faultReasonID = "";
  39. String faultHandle = "";
  40. String faultHandleID = "";
  41. String faultNature = "";
  42. String faultNatureID = "";
  43. String faultDuty = "";
  44. String faultDutyID = "";
  45. String erRecordImg = "";
  46. String recoveryDate = "";
  47. FocusNode _focusNode = FocusNode();
  48. Image mainSignImg = Image.asset(
  49. "assets/images/img_sign.png",
  50. width: 80,
  51. height: 80,
  52. );
  53. Image secondSign = Image.asset(
  54. "assets/images/img_sign.png",
  55. width: 80,
  56. height: 80,
  57. );
  58. var mainSignImgByte;
  59. var mainSignImgByte2;
  60. @override
  61. void initState() {
  62. super.initState();
  63. getFaultList();
  64. }
  65. ///获取急修原因列表
  66. void getFaultList() {
  67. ApiService(context: context).repairFaultTree(widget.item.liftCategory,
  68. onSuccess: (data) {
  69. repairList = data;
  70. setState(() {});
  71. }, onError: (code, msg) {
  72. toasts(msg);
  73. });
  74. }
  75. /// 选择时间
  76. Future<void> _selectTime() async {
  77. DatePicker.showDateTimePicker(context,
  78. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  79. recoveryDate = "${date.toString().split(".")[0]}";
  80. setState(() {});
  81. }, currentTime: DateTime.now(), locale: LocaleType.zh);
  82. }
  83. void _getImage(int key) async {
  84. try {
  85. var _imageFile = await ImagePicker.pickImage(
  86. source: key == 1 ? ImageSource.camera : ImageSource.gallery,
  87. maxWidth: 800,
  88. imageQuality: 95);
  89. if (_imageFile != null) {
  90. images.add(_imageFile);
  91. setState(() {});
  92. }
  93. } catch (e) {
  94. toasts("没有权限,无法打开相册!");
  95. }
  96. }
  97. ///选择图片
  98. void selectPicker() {
  99. showDialog(
  100. context: context,
  101. builder: (BuildContext context) {
  102. return SimpleDialog(
  103. title: Text("选择方式"),
  104. children: ["拍照", '从手机相册选择'].map((String value) {
  105. return SimpleDialogOption(
  106. child: Text(
  107. "${value}",
  108. style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
  109. ),
  110. onPressed: () {
  111. _getImage(value == '拍照' ? 1 : 0);
  112. Navigator.of(context).pop();
  113. },
  114. );
  115. }).toList());
  116. });
  117. }
  118. var faultTitle = ["故障部位和现象", "故障原因", "故障处理", "故障性质", "故障责任"];
  119. ///点击故障
  120. _clickFault(int index) {
  121. if (repairList.length == 0) {
  122. toasts("正在获取故障数据...");
  123. return;
  124. }
  125. RepairFaultEntity obj;
  126. for (var i = 0; i < repairList.length; ++i) {
  127. RepairFaultEntity item = repairList[i];
  128. print(item.faultCategory);
  129. print(faultTitle[index]);
  130. if (item.faultCategory == faultTitle[index]) {
  131. obj = item;
  132. }
  133. }
  134. String jsonString = convert.jsonEncode(obj);
  135. NavigatorUtils.pushResult(context,
  136. "${RepairRouter.repairFaultPage}?title=${Uri.encodeComponent(faultTitle[index])}&item=${Uri.encodeComponent(jsonString)}",
  137. (result) {
  138. var res = result as Map<String, String>;
  139. res.forEach((k, v) {
  140. if (index == 0) {
  141. faultPart = faultPart + "${faultPart.length > 0 ? "," : ""}" + v;
  142. faultPartID =
  143. faultPartID + "${faultPartID.length > 0 ? "," : ""}" + k;
  144. } else if (index == 1) {
  145. faultReason =
  146. faultReason + "${faultReason.length > 0 ? "," : ""}" + v;
  147. faultReasonID =
  148. faultReasonID + "${faultReasonID.length > 0 ? "," : ""}" + k;
  149. } else if (index == 2) {
  150. faultHandle =
  151. faultHandle + "${faultHandle.length > 0 ? "," : ""}" + v;
  152. faultHandleID =
  153. faultHandleID + "${faultHandleID.length > 0 ? "," : ""}" + k;
  154. } else if (index == 3) {
  155. faultNature =
  156. faultNature + "${faultNature.length > 0 ? "," : ""}" + v;
  157. faultNatureID =
  158. faultNatureID + "${faultNatureID.length > 0 ? "," : ""}" + k;
  159. } else if (index == 4) {
  160. faultDuty = faultDuty + "${faultDuty.length > 0 ? "," : ""}" + v;
  161. faultDutyID =
  162. faultDutyID + "${faultDutyID.length > 0 ? "," : ""}" + k;
  163. }
  164. setState(() {});
  165. });
  166. });
  167. }
  168. _saveRepairOrder() async {
  169. if (mainSignImgByte == null) {
  170. toasts("请签名");
  171. return;
  172. }
  173. if (recoveryDate.length == 0) {
  174. toasts("请选择恢复时间");
  175. return;
  176. }
  177. if (images.length == 0) {
  178. toasts("请上传急修图片");
  179. return;
  180. }
  181. showLoading(context, "提交中...");
  182. List<File> signList = [];
  183. String file1 = await ImageUtils()
  184. .saveCacheImageFile(mainSignImgByte, "sign1_${widget.item.id}");
  185. signList.add(File(file1));
  186. String file2;
  187. if (mainSignImgByte2 != null) {
  188. file2 = await ImageUtils()
  189. .saveCacheImageFile(mainSignImgByte2, "sign2_${widget.item.id}");
  190. signList.add(File(file2));
  191. }
  192. ///上传急修图片
  193. ApiService(context: context).uploadMore(images,
  194. onSuccess: (List<String> data) {
  195. print(signList);
  196. ///上传签名图片
  197. ApiService(context: context).uploadMore(signList,
  198. onSuccess: (List<String> signData) {
  199. if (signData != null && signData.length > 0) {
  200. ApiService(context: context).repairSaveOrder(
  201. widget.item.id,
  202. recoveryDate,
  203. data,
  204. _controller.text.toString(),
  205. signData.length > 0 ? signData[0] : "",
  206. signData.length > 1 ? signData[1] : "",
  207. faultPartID,
  208. faultReasonID,
  209. faultHandleID,
  210. faultNatureID,
  211. faultDutyID, onSuccess: (data) {
  212. dismissLoading(context);
  213. if (data != null && data) {
  214. showAlert(context, "提示", "保存成功", "确定", () {
  215. NavigatorUtils.goBack(context);
  216. NavigatorUtils.goBackWithParams(context, true);
  217. });
  218. }
  219. }, onError: (code, msg) {
  220. dismissLoading(context);
  221. toasts(msg);
  222. });
  223. }
  224. }, onError: (code, msg) {
  225. toasts(msg);
  226. dismissLoading(context);
  227. });
  228. }, onError: (code, msg) {
  229. toasts(msg);
  230. dismissLoading(context);
  231. });
  232. }
  233. @override
  234. Widget build(BuildContext context) {
  235. return Scaffold(
  236. //resizeToAvoidBottomPadding: false,
  237. appBar: MyAppBar(
  238. centerTitle: "急修单",
  239. actions: <Widget>[
  240. FlatButton(
  241. child: Text("保存", key: const Key('actionName')),
  242. textColor: Colours.dark_text,
  243. highlightColor: Colors.transparent,
  244. onPressed: () {
  245. _saveRepairOrder();
  246. },
  247. )
  248. ],
  249. ),
  250. body: SafeArea(
  251. child: Container(
  252. color: ThemeUtils.getBackgroundColor(context),
  253. child: Column(
  254. children: <Widget>[
  255. Expanded(
  256. flex: 1,
  257. child: defaultTargetPlatform == TargetPlatform.iOS
  258. ? FormKeyboardActions(child: _buildBody())
  259. : SingleChildScrollView(child: _buildBody()),
  260. ),
  261. ],
  262. ),
  263. ),
  264. ));
  265. }
  266. _buildBody() {
  267. return Padding(
  268. padding: EdgeInsets.only(bottom: 30),
  269. child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <
  270. Widget>[
  271. ClickItem(
  272. title: "故障部位",
  273. hintText: "请选择",
  274. maxLines: 10,
  275. content: "${faultPart}",
  276. onTap: () {
  277. _clickFault(0);
  278. },
  279. ),
  280. ClickItem(
  281. title: "故障原因",
  282. hintText: "请选择",
  283. maxLines: 10,
  284. content: "${faultReason}",
  285. onTap: () {
  286. _clickFault(1);
  287. },
  288. ),
  289. ClickItem(
  290. title: "故障处理",
  291. hintText: "请选择",
  292. maxLines: 10,
  293. content: "${faultHandle}",
  294. onTap: () {
  295. _clickFault(2);
  296. },
  297. ),
  298. ClickItem(
  299. title: "故障性质",
  300. hintText: "请选择",
  301. maxLines: 10,
  302. content: "${faultNature}",
  303. onTap: () {
  304. _clickFault(3);
  305. },
  306. ),
  307. ClickItem(
  308. title: "故障责任",
  309. hintText: "请选择",
  310. maxLines: 10,
  311. content: "${faultDuty}",
  312. onTap: () {
  313. _clickFault(4);
  314. },
  315. ),
  316. SizedBox(
  317. height: 8,
  318. ),
  319. ClickItem(
  320. title: "现场情况描述",
  321. hintText: "",
  322. ),
  323. Container(
  324. color: ThemeUtils.getTabsBg(context),
  325. child: Padding(
  326. padding: const EdgeInsets.only(
  327. top: 5, left: 15.0, right: 15.0, bottom: 8.0),
  328. child: TextField(
  329. maxLength: 30,
  330. maxLines: 3,
  331. // autofocus: false,
  332. focusNode: _focusNode,
  333. controller: _controller,
  334. // keyboardType: widget.keyboardType,
  335. //style: TextStyles.textDark14,
  336. decoration: InputDecoration(
  337. hintText: "填写现场情况描述",
  338. border: InputBorder.none,
  339. hintStyle: TextStyles.textGray14)),
  340. ),
  341. ),
  342. SizedBox(
  343. height: 8,
  344. ),
  345. ClickItem(
  346. title: "恢复时间",
  347. hintText: "请选择",
  348. content: recoveryDate,
  349. onTap: () {
  350. if (_focusNode.hasFocus) {
  351. _focusNode.unfocus();
  352. }
  353. _selectTime();
  354. },
  355. ),
  356. SizedBox(
  357. height: 8,
  358. ),
  359. ClickItem(
  360. title: "上传修理图片",
  361. hintText: "",
  362. ),
  363. Container(
  364. color: ThemeUtils.getTabsBg(context),
  365. child: GridView.builder(
  366. shrinkWrap: true,
  367. padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  368. physics: NeverScrollableScrollPhysics(),
  369. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  370. crossAxisCount: 3, childAspectRatio: 1.18),
  371. itemCount: images.length >= 9 ? 9 : images.length + 1,
  372. itemBuilder: (_, index) {
  373. return Stack(
  374. children: <Widget>[
  375. Center(
  376. child: SelectedImage(
  377. image: index < images.length ? images[index] : null,
  378. onTap: () {
  379. if (_focusNode.hasFocus) {
  380. _focusNode.unfocus();
  381. }
  382. if (index < images.length) {
  383. NavigatorUtils.pushResult(
  384. context,
  385. "${MaintenanceRouter.viewImage}?edit=1&img=" +
  386. Uri.encodeComponent(images[index].path),
  387. (res) {
  388. if (res != null) {
  389. images.removeAt(index);
  390. setState(() {});
  391. }
  392. });
  393. } else {
  394. selectPicker();
  395. }
  396. }),
  397. )
  398. ],
  399. );
  400. },
  401. )),
  402. SizedBox(
  403. height: 8,
  404. ),
  405. ClickItem(
  406. title: "负责人签名",
  407. hintText: "",
  408. ),
  409. Container(
  410. padding: EdgeInsets.all(15),
  411. color: ThemeUtils.getTabsBg(context),
  412. child: Row(
  413. mainAxisAlignment: MainAxisAlignment.start,
  414. children: <Widget>[
  415. GestureDetector(
  416. onTap: () {
  417. if (_focusNode.hasFocus) {
  418. _focusNode.unfocus();
  419. }
  420. NavigatorUtils.pushResult(
  421. context, RepairRouter.repairSignaturePage,
  422. (result) {
  423. if (result != null) {
  424. mainSignImgByte = result;
  425. Image image = Image.memory(result);
  426. setState(() {
  427. mainSignImg = image;
  428. });
  429. }
  430. });
  431. },
  432. child: Container(
  433. color: ThemeUtils.getTabsBg(context),
  434. alignment: Alignment.center,
  435. child: Stack(
  436. alignment: Alignment.center,
  437. children: <Widget>[
  438. Container(
  439. width: 80, height: 80, child: mainSignImg),
  440. Positioned(
  441. child: Text(
  442. "主要急修人员",
  443. style: TextStyle(
  444. fontSize: 12, color: Colours.text_gray_c),
  445. )),
  446. ],
  447. ),
  448. )),
  449. SizedBox(
  450. width: 15,
  451. ),
  452. GestureDetector(
  453. onTap: () {
  454. if (_focusNode.hasFocus) {
  455. _focusNode.unfocus();
  456. }
  457. NavigatorUtils.pushResult(
  458. context, RepairRouter.repairSignaturePage,
  459. (result) {
  460. if (result != null) {
  461. mainSignImgByte2 = result;
  462. Image image = Image.memory(result);
  463. setState(() {
  464. secondSign = image;
  465. });
  466. // _saveFile(result,"sign2").then((res){
  467. // print(res);
  468. // secondSign = res;
  469. // setState(() {
  470. //
  471. // });
  472. // });
  473. }
  474. });
  475. },
  476. child: Container(
  477. color: ThemeUtils.getTabsBg(context),
  478. alignment: Alignment.center,
  479. child: Stack(
  480. alignment: Alignment.center,
  481. children: <Widget>[
  482. Positioned(
  483. child: Text(
  484. "次要急修人员",
  485. style: TextStyle(
  486. fontSize: 12, color: Colours.text_gray_c),
  487. )),
  488. Container(width: 80, height: 80, child: secondSign),
  489. ],
  490. ),
  491. ))
  492. ],
  493. ))
  494. ]));
  495. }
  496. }