maintenance_submit_page.dart 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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:image_picker/image_picker.dart';
  6. import 'package:liftmanager/cache/cache_manager.dart';
  7. import 'package:liftmanager/internal/maintenance/maintenance_router.dart';
  8. import 'package:liftmanager/internal/maintenance/model/maintenance_detail_item.dart';
  9. import 'package:liftmanager/internal/maintenance/model/maintenance_list_entity.dart';
  10. import 'package:liftmanager/internal/maintenance/model/maintenance_options_item.dart';
  11. import 'package:liftmanager/internal/maintenance/provider/maintenance_detail_page_provider.dart';
  12. import 'package:liftmanager/internal/maintenance/widgets/maintenance_options.dart';
  13. import 'package:liftmanager/internal/maintenance/widgets/unselected_options.dart';
  14. import 'package:liftmanager/internal/repair/repair_router.dart';
  15. import 'package:liftmanager/net/api_service.dart';
  16. import 'package:liftmanager/res/resources.dart';
  17. import 'package:liftmanager/routers/fluro_navigator.dart';
  18. import 'package:liftmanager/utils/image_utils.dart';
  19. import 'package:liftmanager/utils/theme_utils.dart';
  20. import 'package:liftmanager/utils/toast.dart';
  21. import 'package:liftmanager/widgets/app_bar.dart';
  22. import 'package:liftmanager/widgets/click_item.dart';
  23. import 'package:liftmanager/widgets/selected_image.dart';
  24. import 'package:oktoast/oktoast.dart';
  25. import 'package:provider/provider.dart' as p;
  26. class MaintenanceSubmitPage extends StatefulWidget {
  27. MaintenanceSubmitPage(this.item);
  28. final MaintenanceListItem item;
  29. @override
  30. State<StatefulWidget> createState() {
  31. return MaintenanceSubmitPageState();
  32. }
  33. }
  34. TextEditingController _controller = TextEditingController();
  35. class MaintenanceSubmitPageState extends State<MaintenanceSubmitPage>
  36. with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  37. List<Map> tabs = [
  38. {"id": 0, "name": "机房"},
  39. {"id": 1, "name": "轿顶"},
  40. {"id": 2, "name": "轿厢"},
  41. {"id": 3, "name": "层门"},
  42. {"id": 4, "name": "底坑井道"}
  43. ];
  44. MaintenanceDetailPageProvider provider = MaintenanceDetailPageProvider();
  45. TabController _tabController;
  46. PageController _pageController = PageController(initialPage: 0);
  47. MaintenanceCache maintenanceCache = MaintenanceCache();
  48. List<File> images = [];
  49. String mainSignImgByte = "";
  50. String mainSignImgByte2 = "";
  51. Image mainSignImg = Image.asset(
  52. "assets/images/img_sign.png",
  53. width: 80,
  54. height: 80,
  55. );
  56. Image secondSign = Image.asset(
  57. "assets/images/img_sign.png",
  58. width: 80,
  59. height: 80,
  60. );
  61. FocusNode _focusNode = FocusNode();
  62. @override
  63. void initState() {
  64. super.initState();
  65. _controller.text = "";
  66. tabs = [
  67. {"id": 0, "name": widget.item.category > 3 ? "第一页" : "机房"},
  68. {"id": 1, "name": widget.item.category > 3 ? "第二页" : "轿顶"},
  69. {"id": 2, "name": widget.item.category > 3 ? "第三页" : "轿厢"},
  70. {"id": 3, "name": widget.item.category > 3 ? "第四页" : "层门"},
  71. {"id": 4, "name": widget.item.category > 3 ? "第五页" : "底坑井道"}
  72. ];
  73. _tabController = new TabController(vsync: this, length: tabs.length);
  74. getLocData();
  75. }
  76. @override
  77. void dispose() {
  78. _tabController.dispose();
  79. super.dispose();
  80. }
  81. ///选择图片
  82. void selectPicker() {
  83. _getImage(1);
  84. // showDialog(
  85. // context: context,
  86. // builder: (BuildContext context) {
  87. // return SimpleDialog(
  88. // title: Text("选择方式"),
  89. // children: ["拍照", '从手机相册选择'].map((String value) {
  90. // print("$value");
  91. // return SimpleDialogOption(
  92. // child: Text(
  93. // "${value}",
  94. // style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
  95. // ),
  96. // onPressed: () {
  97. // _getImage(value == '拍照' ? 1 : 0);
  98. // Navigator.of(context).pop();
  99. // },
  100. // );
  101. // }).toList());
  102. // });
  103. }
  104. void _getImage(int key) async {
  105. try {
  106. var _imageFile = await ImagePicker.pickImage(
  107. source: key == 1 ? ImageSource.camera : ImageSource.gallery,
  108. maxWidth: 800,
  109. imageQuality: 95);
  110. if (_imageFile != null) {
  111. var byte = await _imageFile.readAsBytes();
  112. print(byte.length);
  113. print(_imageFile.path);
  114. images.add(_imageFile);
  115. setState(() {});
  116. }
  117. } catch (e) {
  118. toasts("没有权限,无法打开相机!");
  119. }
  120. }
  121. _onPageChange(int index) {
  122. _tabController.animateTo(index);
  123. provider.setIndex(index);
  124. }
  125. Future _getOptions() async {
  126. ApiService(context: context)
  127. .maintenanceOptions(widget.item.maintenanceType, widget.item.category,
  128. onSuccess: (List<MaintenanceOptionsItem> datas) {
  129. initImage();
  130. initOptions(datas);
  131. setState(() {});
  132. }, onError: (code, msg) {
  133. showToast(msg);
  134. });
  135. }
  136. initImage() {
  137. if (maintenanceCache.id.length == 0) {
  138. return;
  139. }
  140. for (var i = 0; i < maintenanceCache.images.length; ++i) {
  141. var imageFilePath = maintenanceCache.images[i];
  142. images.add(File(imageFilePath));
  143. }
  144. _controller.text = maintenanceCache.advice;
  145. if (maintenanceCache.sign1.length > 0) {
  146. print("111");
  147. mainSignImgByte = maintenanceCache.sign1;
  148. mainSignImg = Image.file(File(maintenanceCache.sign1));
  149. }
  150. if (maintenanceCache.sign2.length > 0) {
  151. print("111");
  152. mainSignImgByte2 = maintenanceCache.sign2;
  153. secondSign = Image.file(File(maintenanceCache.sign2));
  154. }
  155. }
  156. ///初始化维保项
  157. void initOptions(List<MaintenanceOptionsItem> datas) {
  158. Map<String, int> map = maintenanceCache.getMaintenanceOptionArr();
  159. Map<int, List<MaintenanceOptionsItem>> _optionsMap = {
  160. 1: [],
  161. 2: [],
  162. 3: [],
  163. 4: [],
  164. 5: []
  165. };
  166. if (widget.item.liftType == 1) {
  167. for (var i = 0; i < datas.length; ++i) {
  168. var item = datas[i];
  169. item.status = map[item.id] ?? -1;
  170. if ([1, 2, 3, 4, 5].contains(item.sort)) {
  171. if (datas[item.sort] == null) _optionsMap[item.sort] = [];
  172. _optionsMap[item.sort].add(item);
  173. provider.setOptions(_optionsMap);
  174. }
  175. }
  176. } else {
  177. for (var i = 0; i < datas.length; ++i) {
  178. var item = datas[i];
  179. item.status = map[item.id] ?? -1;
  180. int length = datas.length ~/ 5 + 1;
  181. if (i < length) {
  182. _optionsMap[1].add(item);
  183. provider.setOptions(_optionsMap);
  184. } else if (i < length * 2) {
  185. _optionsMap[2].add(item);
  186. provider.setOptions(_optionsMap);
  187. } else if (i < length * 3) {
  188. _optionsMap[3].add(item);
  189. provider.setOptions(_optionsMap);
  190. } else if (i < length * 4) {
  191. _optionsMap[4].add(item);
  192. provider.setOptions(_optionsMap);
  193. } else if (i < length * 5) {
  194. _optionsMap[5].add(item);
  195. provider.setOptions(_optionsMap);
  196. }
  197. // if ([1, 2, 3, 4, 5].contains(item.sort)) {
  198. // if (datas[item.sort] == null) _optionsMap[item.sort] = [];
  199. // _optionsMap[item.sort].add(item);
  200. // provider.setOptions(_optionsMap);
  201. // }
  202. }
  203. }
  204. }
  205. //保存签名图片
  206. Future<String> saveSignImage(index, res) async {
  207. if (res != null) {
  208. String filePath = await ImageUtils()
  209. .saveCacheImageFile(res, "mr_sign${index}_${widget.item.recordId}");
  210. return filePath;
  211. }
  212. return "";
  213. }
  214. _checkMrData(Map<int, List<MaintenanceOptionsItem>> map) {
  215. // if (_controller.text.toString().length == 0) {
  216. // toasts("请输入保养建议");
  217. // return;
  218. // }
  219. if (images.length == 0) {
  220. toasts("请上传保养图片");
  221. return;
  222. }
  223. if (mainSignImgByte.length == 0) {
  224. toasts("请签名");
  225. return;
  226. }
  227. List<MaintenanceOptionsItem> unSelectedList = [];
  228. List<MaintenanceOptionsItem> selectedList = [];
  229. for (var i = 1; i < map.length + 1; ++i) {
  230. var list = map[i];
  231. for (var j = 0; j < list.length; ++j) {
  232. var item = list[j];
  233. if (item.status == -1) {
  234. unSelectedList.add(item);
  235. } else {
  236. selectedList.add(item);
  237. }
  238. }
  239. }
  240. if (unSelectedList.length == 0) {
  241. _sendMrData(selectedList);
  242. } else {
  243. bool isDark = ThemeUtils.isDark(context);
  244. UnSelectedOptions dialogWidget = UnSelectedOptions(unSelectedList);
  245. showDialog(
  246. barrierDismissible: false,
  247. context: context,
  248. builder: (context) => new AlertDialog(
  249. backgroundColor: isDark ? Colours.dark_bg_gray : Colors.white,
  250. content: dialogWidget,
  251. actions: <Widget>[
  252. new FlatButton(
  253. onPressed: () {
  254. setState(() {});
  255. Navigator.pop(context);
  256. },
  257. child: new Text("返回"),
  258. ),
  259. FlatButton(
  260. onPressed: () {
  261. Navigator.pop(context);
  262. selectedList.addAll(dialogWidget.mList);
  263. setState(() {});
  264. // Navigator.pop(context);
  265. // _sendMrData(selectedList);
  266. },
  267. child: new Text('确定'),
  268. )
  269. ],
  270. ),
  271. );
  272. }
  273. }
  274. ///提交维保单
  275. _sendMrData(List<MaintenanceOptionsItem> list) async {
  276. List<File> signList = [];
  277. signList.add(File(mainSignImgByte));
  278. if (mainSignImgByte2.length > 0) {
  279. signList.add(File(mainSignImgByte2));
  280. }
  281. List options = [];
  282. for (var j = 0; j < list.length; ++j) {
  283. var item = list[j];
  284. print("${item.item}:${item.status}");
  285. options.add("${item.id}:${item.status}");
  286. }
  287. showLoading(context, "上传保养图片...");
  288. ///上传保养图片
  289. ApiService(context: context).uploadMore(images,
  290. name: widget.item.workerName,
  291. code: widget.item.registrationCode, onSuccess: (imgs) {
  292. ///上传签名图片
  293. dismissLoading(context);
  294. showLoading(context, "上传签名图片...");
  295. ApiService(context: context).uploadMore(signList, onSuccess: (signs) {
  296. dismissLoading(context);
  297. showLoading(context, "提交保养单...");
  298. ApiService(context: context).maintenanceRecordModify(
  299. widget.item.recordId,
  300. _controller.text.toString(),
  301. options.toString().substring(1, options.toString().length - 1),
  302. signs.length > 0 ? signs[0] : "",
  303. signs.length > 1 ? signs[1] : "",
  304. imgs, onSuccess: (data) {
  305. dismissLoading(context);
  306. deleteJSON("${widget.item.recordId}");
  307. showAlert(context, "提示", "保存成功", "确定", () {
  308. NavigatorUtils.goBack(context);
  309. NavigatorUtils.goBackWithParams(context, true);
  310. // NavigatorUtils.goBack(context);
  311. });
  312. }, onError: (code, msg) {
  313. dismissLoading(context);
  314. toasts(msg);
  315. });
  316. }, onError: (code, msg) {
  317. dismissLoading(context);
  318. toasts(msg);
  319. });
  320. }, onError: (code, msg) {
  321. dismissLoading(context);
  322. toasts(msg);
  323. });
  324. }
  325. ///获取本地数据
  326. void getLocData() {
  327. readJSON("${widget.item.recordId}").then((res) {
  328. print(res);
  329. if (res != null) {
  330. maintenanceCache = MaintenanceCache.fromJsonMap(res);
  331. } else {
  332. maintenanceCache.images = [];
  333. }
  334. _getOptions();
  335. });
  336. }
  337. ///保存维保数据
  338. Future<bool> saveLocData(Map<int, List<MaintenanceOptionsItem>> map) async {
  339. print(map);
  340. List<MaintenanceOptionsItem> mapList = [];
  341. for (int i = 1; i < map.length + 1; i++) {
  342. var list = map[i];
  343. for (int j = 0; j < list.length; j++) {
  344. var item = list[j];
  345. mapList.add(item);
  346. }
  347. }
  348. String options = '';
  349. for (int i = 0; i < mapList.length; i++) {
  350. if (options.length == 0) {
  351. options = options + "${mapList[i].id}:${mapList[i].status}";
  352. } else {
  353. options = options + ",${mapList[i].id}:${mapList[i].status}";
  354. }
  355. }
  356. maintenanceCache.id = widget.item.recordId;
  357. maintenanceCache.options = options;
  358. maintenanceCache.advice = _controller.text.toString();
  359. if (mainSignImgByte.length > 0) {
  360. maintenanceCache.sign1 = mainSignImgByte;
  361. }
  362. if (mainSignImgByte2.length > 0) {
  363. maintenanceCache.sign2 = mainSignImgByte2;
  364. }
  365. maintenanceCache.images = [];
  366. for (var i = 0; i < images.length; ++i) {
  367. var image = images[i];
  368. maintenanceCache.images.add(image.path);
  369. }
  370. bool isSuccess =
  371. await writeJSON("${widget.item.recordId}", maintenanceCache.toJson());
  372. toasts("${isSuccess ? '暂存成功' : '暂存失败'}");
  373. }
  374. _backAction(){
  375. showAlert(
  376. context,
  377. "提示",
  378. "尚未保存,是否退出",
  379. "直接退出",
  380. () {
  381. Navigator.pop(context);
  382. FocusScope.of(context).unfocus();
  383. NavigatorUtils.goBackWithParams(context, true);
  384. },
  385. txt2: "暂存后退出",
  386. onPre2: () {
  387. saveLocData(provider.optionsMap);
  388. Navigator.pop(context);
  389. FocusScope.of(context).unfocus();
  390. NavigatorUtils.goBackWithParams(context, true);
  391. });
  392. }
  393. @override
  394. Widget build(BuildContext context) {
  395. return p.ChangeNotifierProvider<MaintenanceDetailPageProvider>(
  396. create: (_) => provider,
  397. child: WillPopScope(
  398. onWillPop: () {
  399. _backAction();
  400. return Future.value(false);
  401. },
  402. child: Scaffold(
  403. appBar: MyAppBar(
  404. centerTitle: "日常保养",
  405. onBack: () {
  406. _backAction();
  407. },
  408. actions: <Widget>[
  409. FlatButton(
  410. child: Text("暂存", key: const Key('actionName')),
  411. textColor: Colours.dark_text,
  412. highlightColor: Colors.transparent,
  413. onPressed: () {
  414. saveLocData(provider.optionsMap);
  415. },
  416. ),
  417. FlatButton(
  418. child: Text("保存", key: const Key('actionName')),
  419. textColor: Colours.dark_text,
  420. highlightColor: Colors.transparent,
  421. onPressed: () {
  422. _checkMrData(provider.optionsMap);
  423. },
  424. )
  425. ],
  426. ),
  427. body: Column(
  428. crossAxisAlignment: CrossAxisAlignment.start,
  429. children: <Widget>[
  430. Row(children: <Widget>[
  431. Expanded(
  432. flex: 1,
  433. child: Container(
  434. // 隐藏点击效果
  435. color: ThemeUtils.getTabsBg(context),
  436. child: TabBar(
  437. onTap: (index) {
  438. if (!mounted) {
  439. return;
  440. }
  441. _pageController.jumpToPage(index);
  442. },
  443. isScrollable: true,
  444. controller: _tabController,
  445. labelStyle: TextStyles.textBold18,
  446. indicatorSize: TabBarIndicatorSize.label,
  447. // labelPadding: const EdgeInsets.only(left: 16.0),
  448. unselectedLabelColor: Colours.text_gray,
  449. labelColor: Theme.of(context).primaryColor,
  450. indicatorPadding:
  451. const EdgeInsets.only(left: 5.0, right: 5.0),
  452. tabs: tabs.map((map) {
  453. return _TabView(
  454. "${map["name"]}", "", map["id"]);
  455. }).toList()),
  456. ))
  457. ]),
  458. Gaps.line,
  459. Expanded(
  460. child: PageView.builder(
  461. key: const Key('pageView'),
  462. itemCount: tabs.length,
  463. onPageChanged: _onPageChange,
  464. controller: _pageController,
  465. itemBuilder: (BuildContext context, int index) {
  466. if (index == 4) {
  467. return ListView(
  468. children: <Widget>[
  469. Container(
  470. color: ThemeUtils.getBackgroundColor(context),
  471. child: MaintenanceOptions(
  472. index: index,
  473. items: provider.optionsMap[index + 1],
  474. type: widget.item.maintenanceType,
  475. liftType: widget.item.liftType,
  476. isEdit: true,
  477. )),
  478. Container(
  479. color: ThemeUtils.getBackgroundColor(context),
  480. child: uploadView()),
  481. // child: MaintenanceOptions(index: index,items:_optionsMap[index+1],type: widget.type, liftType: widget.liftType,));
  482. ],
  483. );
  484. } else {
  485. return Container(
  486. color: ThemeUtils.getBackgroundColor(context),
  487. child: MaintenanceOptions(
  488. index: index,
  489. items: provider.optionsMap[index + 1],
  490. type: widget.item.maintenanceType,
  491. liftType: widget.item.liftType,
  492. isEdit: true,
  493. ));
  494. }
  495. },
  496. ),
  497. )
  498. ],
  499. ),
  500. )));
  501. }
  502. ///第五页底部
  503. Widget uploadView() {
  504. bool isDark = ThemeUtils.isDark(context);
  505. return Container(
  506. padding: EdgeInsets.fromLTRB(15, 5, 15, 5),
  507. decoration: BoxDecoration(
  508. borderRadius: BorderRadius.circular(6),
  509. ),
  510. child: Column(
  511. crossAxisAlignment: CrossAxisAlignment.start,
  512. children: <Widget>[
  513. // ClickItem(
  514. // title: "停梯时间",
  515. // content: "${widget.item.sto}",
  516. // ),
  517. ClickItem(
  518. title: "保养建议",
  519. hintText: "",
  520. ),
  521. Container(
  522. color: isDark ? Colours.dark_bg_gray : Colors.white,
  523. child: Padding(
  524. padding: const EdgeInsets.only(
  525. top: 5, left: 15.0, right: 15.0, bottom: 8.0),
  526. child: TextField(
  527. maxLength: 30,
  528. maxLines: 3,
  529. focusNode: _focusNode,
  530. // autofocus: false,
  531. controller: _controller,
  532. // keyboardType: widget.keyboardType,
  533. //style: TextStyles.textDark14,
  534. decoration: InputDecoration(
  535. hintText: "填写保养建议",
  536. border: InputBorder.none,
  537. hintStyle: TextStyles.textGray14)),
  538. ),
  539. ),
  540. ClickItem(
  541. title: "保养图片",
  542. hintText: "",
  543. ),
  544. Container(
  545. color: isDark ? Colours.dark_bg_gray : Colors.white,
  546. child: GridView.builder(
  547. shrinkWrap: true,
  548. padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  549. physics: NeverScrollableScrollPhysics(),
  550. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  551. crossAxisCount: 3, childAspectRatio: 1.18),
  552. itemCount: images.length >= 9 ? 9 : images.length + 1,
  553. itemBuilder: (_, index) {
  554. return Stack(
  555. children: <Widget>[
  556. Center(
  557. child: SelectedImage(
  558. image: index < images.length ? images[index] : null,
  559. onTap: () {
  560. if (_focusNode.hasFocus) {
  561. _focusNode.unfocus();
  562. }
  563. if (index < images.length) {
  564. NavigatorUtils.pushResult(
  565. context,
  566. "${MaintenanceRouter.viewImage}?edit=1&img=" +
  567. Uri.encodeComponent(images[index].path),
  568. (res) {
  569. if (res != null) {
  570. images.removeAt(index);
  571. setState(() {});
  572. }
  573. });
  574. } else {
  575. selectPicker();
  576. }
  577. }),
  578. ),
  579. ],
  580. );
  581. },
  582. )),
  583. SizedBox(
  584. height: 8,
  585. ),
  586. ClickItem(
  587. title: "负责人签名",
  588. hintText: "",
  589. ),
  590. Container(
  591. padding: EdgeInsets.all(15),
  592. color: isDark ? Colours.dark_bg_gray : Colors.white,
  593. child: Row(
  594. mainAxisAlignment: MainAxisAlignment.start,
  595. children: <Widget>[
  596. GestureDetector(
  597. onTap: () {
  598. if (_focusNode.hasFocus) {
  599. _focusNode.unfocus();
  600. }
  601. NavigatorUtils.pushResult(
  602. context, RepairRouter.repairSignaturePage,
  603. (result) async {
  604. if (result != null) {
  605. mainSignImgByte = await saveSignImage(1, result);
  606. Image image = Image.memory(result);
  607. setState(() {
  608. mainSignImg = image;
  609. });
  610. // _saveFile(result,"sign1").then((res){
  611. // mainSignImg = res;
  612. // setState(() {
  613. //
  614. // });
  615. // });
  616. }
  617. });
  618. },
  619. child: Container(
  620. color: isDark ? Colours.dark_bg_gray : Colors.white,
  621. alignment: Alignment.center,
  622. child: Stack(
  623. alignment: Alignment.center,
  624. children: <Widget>[
  625. Positioned(
  626. child: Text(
  627. "主要维保人员",
  628. style: TextStyle(
  629. fontSize: 12, color: Colours.text_gray_c),
  630. )),
  631. Container(
  632. width: 150, height: 150, child: mainSignImg),
  633. ],
  634. ),
  635. )),
  636. SizedBox(
  637. width: 15,
  638. ),
  639. GestureDetector(
  640. onTap: () {
  641. if (_focusNode.hasFocus) {
  642. _focusNode.unfocus();
  643. }
  644. NavigatorUtils.pushResult(
  645. context, RepairRouter.repairSignaturePage,
  646. (result) async {
  647. if (result != null) {
  648. // mainSignImgByte2 = result;
  649. mainSignImgByte2 = await saveSignImage(2, result);
  650. Image image = Image.memory(result);
  651. setState(() {
  652. secondSign = image;
  653. });
  654. // _saveFile(result,"sign2").then((res){
  655. // print(res);
  656. // secondSign = res;
  657. // setState(() {
  658. //
  659. // });
  660. // });
  661. }
  662. });
  663. },
  664. child: Container(
  665. color: isDark ? Colours.dark_bg_gray : Colors.white,
  666. alignment: Alignment.center,
  667. child: Stack(
  668. alignment: Alignment.center,
  669. children: <Widget>[
  670. Positioned(
  671. child: Text(
  672. "次要维保人员",
  673. style: TextStyle(
  674. fontSize: 12, color: Colours.text_gray_c),
  675. )),
  676. Container(
  677. width: 150, height: 150, child: secondSign),
  678. ],
  679. ),
  680. ))
  681. ],
  682. ))
  683. ],
  684. ),
  685. );
  686. }
  687. @override
  688. bool get wantKeepAlive => true;
  689. }
  690. class _TabView extends StatelessWidget {
  691. const _TabView(this.tabName, this.tabSub, this.index);
  692. final String tabName;
  693. final String tabSub;
  694. final int index;
  695. @override
  696. Widget build(BuildContext context) {
  697. return p.Consumer<MaintenanceDetailPageProvider>(
  698. builder: (_, provider, child) {
  699. return Tab(
  700. child: SizedBox(
  701. child: Row(
  702. crossAxisAlignment: CrossAxisAlignment.center,
  703. mainAxisAlignment: MainAxisAlignment.center,
  704. children: <Widget>[
  705. Text(
  706. tabName,
  707. style: TextStyle(fontSize: 15),
  708. ),
  709. Offstage(
  710. offstage: provider.index != index,
  711. child: Padding(
  712. padding: const EdgeInsets.only(top: 1.0),
  713. child: Text(tabSub,
  714. style: TextStyle(fontSize: Dimens.font_sp12)),
  715. )),
  716. ],
  717. ),
  718. ));
  719. },
  720. );
  721. }
  722. }