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.goBack(context);
  310. NavigatorUtils.goBackWithParams(context, true);
  311. // NavigatorUtils.goBack(context);
  312. });
  313. }, onError: (code, msg) {
  314. dismissLoading(context);
  315. toasts(msg);
  316. });
  317. }, onError: (code, msg) {
  318. dismissLoading(context);
  319. toasts(msg);
  320. });
  321. }, onError: (code, msg) {
  322. dismissLoading(context);
  323. toasts(msg);
  324. });
  325. }
  326. ///获取本地数据
  327. void getLocData() {
  328. readJSON("${widget.item.recordId}").then((res) {
  329. print(res);
  330. if (res != null) {
  331. maintenanceCache = MaintenanceCache.fromJsonMap(res);
  332. } else {
  333. maintenanceCache.images = [];
  334. }
  335. _getOptions();
  336. });
  337. }
  338. ///保存维保数据
  339. Future<bool> saveLocData(Map<int, List<MaintenanceOptionsItem>> map) async {
  340. print(map);
  341. List<MaintenanceOptionsItem> mapList = [];
  342. for (int i = 1; i < map.length + 1; i++) {
  343. var list = map[i];
  344. for (int j = 0; j < list.length; j++) {
  345. var item = list[j];
  346. mapList.add(item);
  347. }
  348. }
  349. String options = '';
  350. for (int i = 0; i < mapList.length; i++) {
  351. if (options.length == 0) {
  352. options = options + "${mapList[i].id}:${mapList[i].status}";
  353. } else {
  354. options = options + ",${mapList[i].id}:${mapList[i].status}";
  355. }
  356. }
  357. maintenanceCache.id = widget.item.recordId;
  358. maintenanceCache.options = options;
  359. maintenanceCache.advice = _controller.text.toString();
  360. if (mainSignImgByte.length > 0) {
  361. maintenanceCache.sign1 = mainSignImgByte;
  362. }
  363. if (mainSignImgByte2.length > 0) {
  364. maintenanceCache.sign2 = mainSignImgByte2;
  365. }
  366. maintenanceCache.images = [];
  367. for (var i = 0; i < images.length; ++i) {
  368. var image = images[i];
  369. maintenanceCache.images.add(image.path);
  370. }
  371. bool isSuccess =
  372. await writeJSON("${widget.item.recordId}", maintenanceCache.toJson());
  373. toasts("${isSuccess ? '暂存成功' : '暂存失败'}");
  374. }
  375. _backAction() {
  376. showAlert(
  377. context,
  378. "提示",
  379. "尚未保存,是否退出",
  380. "直接退出",
  381. () {
  382. Navigator.pop(context);
  383. FocusScope.of(context).unfocus();
  384. NavigatorUtils.goBackWithParams(context, true);
  385. },
  386. txt2: "暂存后退出",
  387. onPre2: () {
  388. saveLocData(provider.optionsMap);
  389. Navigator.pop(context);
  390. FocusScope.of(context).unfocus();
  391. NavigatorUtils.goBackWithParams(context, true);
  392. });
  393. }
  394. @override
  395. Widget build(BuildContext context) {
  396. return p.ChangeNotifierProvider<MaintenanceDetailPageProvider>(
  397. create: (_) => provider,
  398. child: WillPopScope(
  399. onWillPop: () {
  400. _backAction();
  401. return Future.value(false);
  402. },
  403. child: Scaffold(
  404. appBar: MyAppBar(
  405. centerTitle: "日常保养",
  406. onBack: () {
  407. _backAction();
  408. },
  409. actions: <Widget>[
  410. FlatButton(
  411. child: Text("暂存", key: const Key('actionName')),
  412. textColor: Colours.text,
  413. highlightColor: Colors.transparent,
  414. onPressed: () {
  415. saveLocData(provider.optionsMap);
  416. },
  417. ),
  418. FlatButton(
  419. child: Text("保存", key: const Key('actionName')),
  420. textColor: Colours.text,
  421. highlightColor: Colors.transparent,
  422. onPressed: () {
  423. _checkMrData(provider.optionsMap);
  424. },
  425. )
  426. ],
  427. ),
  428. body: Column(
  429. crossAxisAlignment: CrossAxisAlignment.start,
  430. children: <Widget>[
  431. Row(children: <Widget>[
  432. Expanded(
  433. flex: 1,
  434. child: Container(
  435. // 隐藏点击效果
  436. color: ThemeUtils.getTabsBg(context),
  437. child: TabBar(
  438. onTap: (index) {
  439. if (!mounted) {
  440. return;
  441. }
  442. _pageController.jumpToPage(index);
  443. },
  444. isScrollable: true,
  445. controller: _tabController,
  446. labelStyle: TextStyles.textBold18,
  447. indicatorSize: TabBarIndicatorSize.label,
  448. // labelPadding: const EdgeInsets.only(left: 16.0),
  449. unselectedLabelColor: Colours.text_gray,
  450. labelColor: Theme.of(context).primaryColor,
  451. indicatorPadding:
  452. const EdgeInsets.only(left: 5.0, right: 5.0),
  453. tabs: tabs.map((map) {
  454. return _TabView(
  455. "${map["name"]}", "", map["id"]);
  456. }).toList()),
  457. ))
  458. ]),
  459. Gaps.line,
  460. Expanded(
  461. child: PageView.builder(
  462. key: const Key('pageView'),
  463. itemCount: tabs.length,
  464. onPageChanged: _onPageChange,
  465. controller: _pageController,
  466. itemBuilder: (BuildContext context, int index) {
  467. if (index == 4) {
  468. return ListView(
  469. children: <Widget>[
  470. Container(
  471. color: ThemeUtils.getBackgroundColor(context),
  472. child: MaintenanceOptions(
  473. index: index,
  474. items: provider.optionsMap[index + 1],
  475. type: widget.item.maintenanceType,
  476. liftType: widget.item.liftType,
  477. isEdit: true,
  478. )),
  479. Container(
  480. color: ThemeUtils.getBackgroundColor(context),
  481. child: uploadView()),
  482. // child: MaintenanceOptions(index: index,items:_optionsMap[index+1],type: widget.type, liftType: widget.liftType,));
  483. ],
  484. );
  485. } else {
  486. return Container(
  487. color: ThemeUtils.getBackgroundColor(context),
  488. child: MaintenanceOptions(
  489. index: index,
  490. items: provider.optionsMap[index + 1],
  491. type: widget.item.maintenanceType,
  492. liftType: widget.item.liftType,
  493. isEdit: true,
  494. ));
  495. }
  496. },
  497. ),
  498. )
  499. ],
  500. ),
  501. )));
  502. }
  503. ///第五页底部
  504. Widget uploadView() {
  505. bool isDark = ThemeUtils.isDark(context);
  506. return Container(
  507. padding: EdgeInsets.fromLTRB(15, 5, 15, 5),
  508. decoration: BoxDecoration(
  509. borderRadius: BorderRadius.circular(6),
  510. ),
  511. child: Column(
  512. crossAxisAlignment: CrossAxisAlignment.start,
  513. children: <Widget>[
  514. // ClickItem(
  515. // title: "停梯时间",
  516. // content: "${widget.item.sto}",
  517. // ),
  518. ClickItem(
  519. title: "保养建议",
  520. hintText: "",
  521. ),
  522. Container(
  523. color: isDark ? Colours.dark_bg_gray : Colors.white,
  524. child: Padding(
  525. padding: const EdgeInsets.only(
  526. top: 5, left: 15.0, right: 15.0, bottom: 8.0),
  527. child: TextField(
  528. maxLength: 30,
  529. maxLines: 3,
  530. focusNode: _focusNode,
  531. // autofocus: false,
  532. controller: _controller,
  533. // keyboardType: widget.keyboardType,
  534. //style: TextStyles.textDark14,
  535. decoration: InputDecoration(
  536. hintText: "填写保养建议",
  537. border: InputBorder.none,
  538. hintStyle: TextStyles.textGray14)),
  539. ),
  540. ),
  541. ClickItem(
  542. title: "保养图片",
  543. hintText: "",
  544. ),
  545. Container(
  546. color: isDark ? Colours.dark_bg_gray : Colors.white,
  547. child: GridView.builder(
  548. shrinkWrap: true,
  549. padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0),
  550. physics: NeverScrollableScrollPhysics(),
  551. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  552. crossAxisCount: 3, childAspectRatio: 1.18),
  553. itemCount: images.length >= 9 ? 9 : images.length + 1,
  554. itemBuilder: (_, index) {
  555. return Stack(
  556. children: <Widget>[
  557. Center(
  558. child: SelectedImage(
  559. image: index < images.length ? images[index] : null,
  560. onTap: () {
  561. if (_focusNode.hasFocus) {
  562. _focusNode.unfocus();
  563. }
  564. if (index < images.length) {
  565. NavigatorUtils.pushResult(
  566. context,
  567. "${MaintenanceRouter.viewImage}?edit=1&img=" +
  568. Uri.encodeComponent(images[index].path),
  569. (res) {
  570. if (res != null) {
  571. images.removeAt(index);
  572. setState(() {});
  573. }
  574. });
  575. } else {
  576. selectPicker();
  577. }
  578. }),
  579. ),
  580. ],
  581. );
  582. },
  583. )),
  584. SizedBox(
  585. height: 8,
  586. ),
  587. ClickItem(
  588. title: "负责人签名",
  589. hintText: "",
  590. ),
  591. Container(
  592. padding: EdgeInsets.all(15),
  593. color: isDark ? Colours.dark_bg_gray : Colors.white,
  594. child: Row(
  595. mainAxisAlignment: MainAxisAlignment.start,
  596. children: <Widget>[
  597. GestureDetector(
  598. onTap: () {
  599. if (_focusNode.hasFocus) {
  600. _focusNode.unfocus();
  601. }
  602. NavigatorUtils.pushResult(
  603. context, RepairRouter.repairSignaturePage,
  604. (result) async {
  605. if (result != null) {
  606. mainSignImgByte = await saveSignImage(1, result);
  607. Image image = Image.memory(result);
  608. setState(() {
  609. mainSignImg = image;
  610. });
  611. // _saveFile(result,"sign1").then((res){
  612. // mainSignImg = res;
  613. // setState(() {
  614. //
  615. // });
  616. // });
  617. }
  618. });
  619. },
  620. child: Container(
  621. color: isDark ? Colours.dark_bg_gray : Colors.white,
  622. alignment: Alignment.center,
  623. child: Stack(
  624. alignment: Alignment.center,
  625. children: <Widget>[
  626. Positioned(
  627. child: Text(
  628. "主要维保人员",
  629. style: TextStyle(
  630. fontSize: 12, color: Colours.text_gray_c),
  631. )),
  632. Container(
  633. width: 150, height: 150, child: mainSignImg),
  634. ],
  635. ),
  636. )),
  637. SizedBox(
  638. width: 15,
  639. ),
  640. GestureDetector(
  641. onTap: () {
  642. if (_focusNode.hasFocus) {
  643. _focusNode.unfocus();
  644. }
  645. NavigatorUtils.pushResult(
  646. context, RepairRouter.repairSignaturePage,
  647. (result) async {
  648. if (result != null) {
  649. // mainSignImgByte2 = result;
  650. mainSignImgByte2 = await saveSignImage(2, result);
  651. Image image = Image.memory(result);
  652. setState(() {
  653. secondSign = image;
  654. });
  655. // _saveFile(result,"sign2").then((res){
  656. // print(res);
  657. // secondSign = res;
  658. // setState(() {
  659. //
  660. // });
  661. // });
  662. }
  663. });
  664. },
  665. child: Container(
  666. color: isDark ? Colours.dark_bg_gray : Colors.white,
  667. alignment: Alignment.center,
  668. child: Stack(
  669. alignment: Alignment.center,
  670. children: <Widget>[
  671. Positioned(
  672. child: Text(
  673. "次要维保人员",
  674. style: TextStyle(
  675. fontSize: 12, color: Colours.text_gray_c),
  676. )),
  677. Container(
  678. width: 150, height: 150, child: secondSign),
  679. ],
  680. ),
  681. ))
  682. ],
  683. ))
  684. ],
  685. ),
  686. );
  687. }
  688. @override
  689. bool get wantKeepAlive => true;
  690. }
  691. class _TabView extends StatelessWidget {
  692. const _TabView(this.tabName, this.tabSub, this.index);
  693. final String tabName;
  694. final String tabSub;
  695. final int index;
  696. @override
  697. Widget build(BuildContext context) {
  698. return p.Consumer<MaintenanceDetailPageProvider>(
  699. builder: (_, provider, child) {
  700. return Tab(
  701. child: SizedBox(
  702. child: Row(
  703. crossAxisAlignment: CrossAxisAlignment.center,
  704. mainAxisAlignment: MainAxisAlignment.center,
  705. children: <Widget>[
  706. Text(
  707. tabName,
  708. style: TextStyle(fontSize: 15),
  709. ),
  710. Offstage(
  711. offstage: provider.index != index,
  712. child: Padding(
  713. padding: const EdgeInsets.only(top: 1.0),
  714. child: Text(tabSub,
  715. style: TextStyle(fontSize: Dimens.font_sp12)),
  716. )),
  717. ],
  718. ),
  719. ));
  720. },
  721. );
  722. }
  723. }