repair_submit_page.dart 17 KB

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