patrol_job_detail.dart 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. import 'package:deus_app/common/event/RefreshPatrol.dart';
  2. import 'package:deus_app/common/event/RefreshPatrolEdit.dart';
  3. import 'package:deus_app/common/style/TitleBar.dart';
  4. import 'package:deus_app/common/style/gsy_style.dart';
  5. import 'package:deus_app/common/utils/ConstantString.dart';
  6. import 'package:deus_app/common/utils/ToastUtils.dart';
  7. import 'package:deus_app/main.dart';
  8. import 'package:deus_app/page/patrol/patrol_job_list.dart';
  9. import 'package:flutter/material.dart';
  10. import '../../common/dialog/CloseTaskDialog.dart';
  11. import '../../common/utils/DioUtil.dart';
  12. import '../../generated/json/patrol_job_detail_response_entity_helper.dart';
  13. import '../../model/patrol_job_detail_response_entity.dart';
  14. /**
  15. * 巡检任务详情页面
  16. */
  17. class PatrolJobDetail extends StatefulWidget {
  18. var id;
  19. PatrolJobDetail({super.key, @required this.id});
  20. static var routeName = '/PatrolJobDetail';
  21. @override
  22. State createState() {
  23. print(id);
  24. return new _PatrolJobDetail(id);
  25. }
  26. }
  27. class _PatrolJobDetail extends State<PatrolJobDetail> {
  28. var _event;
  29. var id;
  30. bool type = false;
  31. _PatrolJobDetail(this.id);
  32. List<PatrolJobDetailResponseDataPatrolItemVOS> patrolItemVOS =
  33. <PatrolJobDetailResponseDataPatrolItemVOS>[];
  34. List<PatrolJobDetailResponseDataEquipmentVOS> equipmentVOS =
  35. <PatrolJobDetailResponseDataEquipmentVOS>[];
  36. List<String> fileUrls = <String>[];
  37. PatrolJobDetailResponseData responseData = PatrolJobDetailResponseData();
  38. _load() async {
  39. var result = await DioUtil().request('patrolJob/appGetJobDetail',
  40. method: DioMethod.get, params: {'id': id});
  41. PatrolJobDetailResponseEntity patrolJobResponse =
  42. patrolJobDetailResponseEntityFromJson(
  43. PatrolJobDetailResponseEntity(), result);
  44. if (patrolJobResponse.code == 0) {
  45. setState(() {
  46. responseData = patrolJobResponse.data;
  47. patrolItemVOS.addAll(responseData.patrolItemVOS);
  48. equipmentVOS.addAll(responseData.equipmentVOS);
  49. fileUrls.addAll(responseData.fileUrls);
  50. if (responseData.status == 1 || responseData.status == 4) {
  51. type = true;
  52. }
  53. });
  54. } else {
  55. showToast(patrolJobResponse.msg);
  56. }
  57. }
  58. closeJob(String msg) async {
  59. var result = await DioUtil().request('patrolJob/closeJob',
  60. method: DioMethod.post, data: {'id': id, 'closeReason': msg});
  61. if (0 == result['code']) {
  62. setState(() {
  63. eventBus.fire(RefreshPatrol());
  64. Navigator.pop(context);
  65. });
  66. } else {
  67. showToast(result['msg']);
  68. }
  69. }
  70. @override
  71. void initState() {
  72. super.initState();
  73. _load();
  74. _event = eventBus.on<RefreshPatrolEdit>().listen((event) {
  75. setState(() {
  76. _load();
  77. });
  78. });
  79. }
  80. @override
  81. Widget build(BuildContext context) {
  82. return Scaffold(
  83. resizeToAvoidBottomInset: false,
  84. appBar: TitleBar()
  85. .backAppbar("巡检任务详情"),
  86. backgroundColor: const Color(0xfff2f2f2),
  87. body: Stack(
  88. children: [
  89. Container(
  90. margin: EdgeInsets.only(bottom: type?60:0),
  91. child: ListView(
  92. children: _Ws(),
  93. ),
  94. ),
  95. Visibility(
  96. visible: type,
  97. child: Positioned(
  98. left: 0,
  99. right: 0,
  100. bottom: 0,
  101. // flex: 7,
  102. child: Row(
  103. children: [
  104. Expanded(
  105. child: SizedBox(
  106. height: 50,
  107. child: TextButton(
  108. onPressed: () {
  109. CloseTaskDialog.showCupertinoAlertDialog(context,
  110. (msg) {
  111. closeJob(msg);
  112. });
  113. },
  114. style: ButtonStyle(
  115. backgroundColor: MaterialStateProperty.all<Color>(
  116. Color(0xFF4875EC)),
  117. shape: MaterialStateProperty.all(
  118. BeveledRectangleBorder(
  119. borderRadius: BorderRadius.circular(0))),
  120. foregroundColor: MaterialStateProperty.all<Color>(
  121. Colors.white),
  122. // padding: MaterialStateProperty.all(EdgeInsets.zero)
  123. ),
  124. child: const Text(ConstantString.close_task),
  125. ),
  126. ),
  127. ),
  128. Expanded(
  129. child: SizedBox(
  130. height: 50,
  131. child: TextButton(
  132. onPressed: () {
  133. if (type) {
  134. Navigator.push(
  135. context,
  136. MaterialPageRoute(
  137. builder: (context) =>
  138. PatrolJobList(responseData: responseData)));
  139. }
  140. },
  141. style: ButtonStyle(
  142. backgroundColor:
  143. MaterialStateProperty.all<Color>(Colors.blue),
  144. foregroundColor:
  145. MaterialStateProperty.all<Color>(Colors.white),
  146. shape: MaterialStateProperty.all(
  147. BeveledRectangleBorder(
  148. borderRadius: BorderRadius.circular(0))),
  149. // padding: MaterialStateProperty.all(EdgeInsets.zero)
  150. ),
  151. child: const Text(ConstantString.registration),
  152. ),
  153. )),
  154. ],
  155. ),
  156. ))
  157. ],
  158. ));
  159. }
  160. List<Widget> _Ws() {
  161. List<Widget> ws = [];
  162. ws.add(_patrolJobDetail(responseData));
  163. ws.add(_device());
  164. ws.add(_item());
  165. if ('' != responseData.remarks) {
  166. ws.add(_remark());
  167. }
  168. ws.add(_url());
  169. return ws;
  170. }
  171. Widget _patrolJobDetail(PatrolJobDetailResponseData patrolJobDetailData) {
  172. if ('' != patrolJobDetailData.name) {
  173. return Column(
  174. children: [
  175. Row(
  176. children: [
  177. Container(
  178. margin: EdgeInsets.only(top: 10, left: 12),
  179. // padding: EdgeInsets.fromLTRB(12, 0, 0, 0),
  180. alignment: Alignment.bottomLeft,
  181. child: Text(
  182. patrolJobDetailData.name ?? "",
  183. style: TextStyle(
  184. fontSize: GSYConstant.middleTextWhiteSize,
  185. fontWeight: FontWeight.bold),
  186. ),
  187. ),
  188. Container(
  189. margin: EdgeInsets.only(top: 10, left: 10),
  190. padding: EdgeInsets.fromLTRB(3, 2, 3, 2),
  191. alignment: Alignment.centerLeft,
  192. child: Text(
  193. patrolJobDetailData.status == 0
  194. ? '已关闭'
  195. : patrolJobDetailData.status == 1
  196. ? '执行中'
  197. : patrolJobDetailData.status == 2
  198. ? '已完成'
  199. : patrolJobDetailData.status == 3
  200. ? '待执行'
  201. : patrolJobDetailData.status == 4
  202. ? '已逾期'
  203. : '未知',
  204. style: TextStyle(
  205. fontSize: GSYConstant.minTextSize, color:patrolJobDetailData.status == 0 || patrolJobDetailData.status == 4
  206. ? Colors.red
  207. : patrolJobDetailData.status == 1
  208. ? Colors.orange
  209. : patrolJobDetailData.status == 2
  210. ? Colors.blue
  211. : Colors.black),
  212. ),
  213. decoration: BoxDecoration(
  214. border: new Border.all(
  215. color:patrolJobDetailData.status == 0 || patrolJobDetailData.status == 4
  216. ? Colors.red
  217. : patrolJobDetailData.status == 1
  218. ? Colors.orange
  219. : patrolJobDetailData.status == 2
  220. ? Colors.blue
  221. : Colors.black, //边框颜色
  222. width: 1.0, //边框粗细
  223. ),
  224. borderRadius: const BorderRadius.all(
  225. const Radius.circular(3.0)), //边框的弧度
  226. ),
  227. )
  228. ],
  229. ),
  230. Container(
  231. margin: EdgeInsets.only(top: 10, left: 12, bottom: 12),
  232. alignment: Alignment.centerLeft,
  233. child: Text(
  234. '任务编号: ' + patrolJobDetailData.number,
  235. style: TextStyle(
  236. fontSize: GSYConstant.smallTextSize,
  237. ),
  238. ),
  239. ),
  240. // Divider(
  241. // height: 0.8,
  242. // indent: 5.0,
  243. // endIndent: 5.0,
  244. // color: Colors.grey,
  245. // ),
  246. Container(
  247. decoration: BoxDecoration(color: Colors.white),
  248. child: Column(
  249. children: [
  250. Container(
  251. padding: EdgeInsets.fromLTRB(12, 20, 12, 0),
  252. alignment: Alignment.centerLeft,
  253. child: Row(
  254. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  255. children: [
  256. new Text(
  257. '巡检任务名称:',
  258. style: GSYConstant.smallTextLight,
  259. ),
  260. Container(
  261. child: Text(
  262. patrolJobDetailData.name!,
  263. style: GSYConstant.smallTextLight,
  264. textAlign: TextAlign.right,
  265. ),
  266. ),
  267. ],
  268. ),
  269. ),
  270. Container(
  271. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  272. child: Row(
  273. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  274. children: [
  275. new Text(
  276. '巡检任务编号:',
  277. style: GSYConstant.smallTextLight,
  278. ),
  279. Container(
  280. child: Text(
  281. patrolJobDetailData.number,
  282. style: GSYConstant.smallTextLight,
  283. textAlign: TextAlign.right,
  284. ),
  285. ),
  286. ],
  287. ),
  288. ),
  289. Container(
  290. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  291. child: Row(
  292. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  293. children: [
  294. new Text(
  295. '巡检计划名称:',
  296. style: GSYConstant.smallTextLight,
  297. ),
  298. Container(
  299. child: Text(
  300. patrolJobDetailData.planName ?? "",
  301. style: GSYConstant.smallTextLight,
  302. textAlign: TextAlign.right,
  303. ),
  304. ),
  305. ])),
  306. Container(
  307. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  308. child: Row(
  309. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  310. children: [
  311. new Text(
  312. '巡检计划编号:',
  313. style: GSYConstant.smallTextLight,
  314. ),
  315. Container(
  316. child: Text(
  317. patrolJobDetailData.planNumber!,
  318. style: GSYConstant.smallTextLight,
  319. textAlign: TextAlign.right,
  320. ),
  321. ),
  322. ])),
  323. Container(
  324. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  325. child: Row(
  326. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  327. children: [
  328. new Text(
  329. '周期类型:',
  330. style: GSYConstant.smallTextLight,
  331. ),
  332. Container(
  333. child: Text(
  334. patrolJobDetailData.termType == 1 ? '日计划' : '暂无',
  335. style: GSYConstant.smallTextLight,
  336. textAlign: TextAlign.right,
  337. ),
  338. ),
  339. ])),
  340. Container(
  341. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  342. child: Row(
  343. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  344. children: [
  345. new Text(
  346. '任务开始时间:',
  347. style: GSYConstant.smallTextLight,
  348. ),
  349. Container(
  350. child: Text(
  351. patrolJobDetailData.startDate!,
  352. style: GSYConstant.smallTextLight,
  353. textAlign: TextAlign.right,
  354. ),
  355. ),
  356. ])),
  357. Container(
  358. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  359. child: Row(
  360. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  361. children: [
  362. new Text(
  363. '任务结束时间:',
  364. style: GSYConstant.smallTextLight,
  365. ),
  366. Container(
  367. child: Text(
  368. patrolJobDetailData.endDate!,
  369. style: GSYConstant.smallTextLight,
  370. textAlign: TextAlign.right,
  371. ),
  372. ),
  373. ])),
  374. Container(
  375. padding: EdgeInsets.fromLTRB(12, 15, 12, 0),
  376. child: Row(
  377. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  378. children: [
  379. new Text(
  380. '实际完成时间:',
  381. style: GSYConstant.smallTextLight,
  382. ),
  383. Container(
  384. child: Text(
  385. patrolJobDetailData.finishTime!,
  386. style: GSYConstant.smallTextLight,
  387. textAlign: TextAlign.right,
  388. ),
  389. ),
  390. ])),
  391. Container(
  392. padding: EdgeInsets.fromLTRB(12, 15, 12, 15),
  393. child: Row(
  394. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  395. children: [
  396. new Text(
  397. '巡检人员:',
  398. style: GSYConstant.smallTextLight,
  399. ),
  400. Container(
  401. child: Text(
  402. patrolJobDetailData.personnel!,
  403. style: GSYConstant.smallTextLight,
  404. textAlign: TextAlign.right,
  405. ),
  406. ),
  407. ])),
  408. ],
  409. ),
  410. ),
  411. ],
  412. );
  413. } else {
  414. return Text('暂无数据');
  415. }
  416. }
  417. Widget _device() {
  418. return ExpansionTile(
  419. title: Container(
  420. child: Text(
  421. '巡检设备',
  422. style: GSYConstant.normalTextActionWhiteBold,
  423. )),
  424. children: equipmentVOS.map((e) => _buildDevice(e)).toList(),
  425. initiallyExpanded: true);
  426. }
  427. Widget _buildDevice(PatrolJobDetailResponseDataEquipmentVOS device) {
  428. return FractionallySizedBox(
  429. widthFactor: 1,
  430. child: Container(
  431. margin: device.id ==
  432. responseData
  433. .equipmentVOS![responseData.equipmentVOS!.length - 1].id
  434. ? EdgeInsets.only(bottom: 0)
  435. : EdgeInsets.only(bottom: 5),
  436. decoration: BoxDecoration(color: Colors.white),
  437. padding: const EdgeInsets.fromLTRB(12, 12, 12, 12),
  438. child: Column(
  439. children: [
  440. Container(
  441. // padding: const EdgeInsets.fromLTRB(30.0, 0.0, 0.0, 0.0),
  442. alignment: Alignment.centerLeft,
  443. child: Row(
  444. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  445. children: [
  446. Text(device.showName, style: GSYConstant.smallTextBold),
  447. Text(
  448. device.isComplete == 0 ? '未完成' : '已完成',
  449. style: TextStyle(
  450. fontSize: GSYConstant.smallTextSize,
  451. color: device.isComplete == 0
  452. ? Colors.red
  453. : Colors.blue),
  454. ),
  455. ]),
  456. ),
  457. Container(
  458. margin: const EdgeInsets.only(top: 10),
  459. // padding: const EdgeInsets.fromLTRB(30.0, 0.0, 0.0, 10.0),
  460. // alignment: Alignment.centerLeft,
  461. child: Row(
  462. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  463. children: [
  464. new Text(
  465. '完成时间:',
  466. style: GSYConstant.smallTextLight,
  467. ),
  468. Container(
  469. child: Text(
  470. device.itemCompleteTime,
  471. style: GSYConstant.smallTextLight,
  472. textAlign: TextAlign.right,
  473. ),
  474. ),
  475. ]),
  476. ),
  477. // Divider(
  478. // height: 0.8,
  479. // indent: 10.0,
  480. // endIndent: 10.0,
  481. // color: Colors.grey,
  482. // ),
  483. ],
  484. ),
  485. ));
  486. }
  487. Widget _item() {
  488. return ExpansionTile(
  489. title: Container(
  490. child: Text(
  491. '巡检项目',
  492. style: GSYConstant.normalTextActionWhiteBold,
  493. )),
  494. children: patrolItemVOS.map((e) => _buildItem(e)).toList(),
  495. initiallyExpanded: false);
  496. }
  497. Widget _buildItem(PatrolJobDetailResponseDataPatrolItemVOS item) {
  498. return FractionallySizedBox(
  499. widthFactor: 1,
  500. child: Container(
  501. margin: item.id ==
  502. responseData
  503. .patrolItemVOS[responseData.patrolItemVOS.length - 1].id
  504. ? EdgeInsets.only(bottom: 0)
  505. : EdgeInsets.only(bottom: 5),
  506. padding: const EdgeInsets.fromLTRB(12, 15, 15, 0),
  507. decoration: BoxDecoration(color: Colors.white),
  508. child: Column(
  509. children: [
  510. Container(
  511. alignment: Alignment.centerLeft,
  512. child: Text(item.name,
  513. style: TextStyle(
  514. fontSize: GSYConstant.middleTextWhiteSize,
  515. fontWeight: FontWeight.bold)),
  516. ),
  517. Container(
  518. margin: const EdgeInsets.fromLTRB(0, 10.0, 0, 0),
  519. alignment: Alignment.centerLeft,
  520. child: Text(
  521. item.result,
  522. style: GSYConstant.smallTextLight,
  523. ),
  524. ),
  525. // Divider(
  526. // height: 0.8,
  527. // indent: 10.0,
  528. // endIndent: 10.0,
  529. // color: Colors.grey,
  530. // ),
  531. ],
  532. ),
  533. ));
  534. }
  535. Widget _remark() {
  536. return ExpansionTile(
  537. title: Container(
  538. child: Text(
  539. '任务结果备注',
  540. style: GSYConstant.normalTextActionWhiteBold,
  541. )),
  542. children: [_buildRemark(responseData)],
  543. initiallyExpanded: false);
  544. }
  545. Widget _buildRemark(PatrolJobDetailResponseData patrolJobDetailData) {
  546. return FractionallySizedBox(
  547. widthFactor: 1,
  548. child: Container(
  549. decoration: BoxDecoration(color: Colors.white),
  550. child: Column(
  551. children: [
  552. Container(
  553. margin: const EdgeInsets.fromLTRB(12, 15.0, 12, 15.0),
  554. alignment: Alignment.centerLeft,
  555. child: Text(patrolJobDetailData.remarks,
  556. style: TextStyle(fontSize: 14)),
  557. )
  558. ],
  559. ),
  560. ));
  561. }
  562. Widget _url() {
  563. return ExpansionTile(
  564. title: Container(
  565. child: Text(
  566. '任务图片',
  567. style: GSYConstant.normalTextActionWhiteBold,
  568. )),
  569. children: [
  570. Container(
  571. width: double.infinity,
  572. margin: EdgeInsets.only(bottom: 5),
  573. padding: fileUrls.isNotEmpty?EdgeInsets.only(right: 12, top: 10):EdgeInsets.only(right: 0, top: 0),
  574. color: Colors.white,
  575. child: Wrap(children: fileUrls.map((e) => _buildImage(e)).toList()),
  576. alignment: Alignment.centerLeft,
  577. )
  578. ],
  579. initiallyExpanded: false);
  580. }
  581. Widget _buildImage(String imageData) {
  582. return Container(
  583. margin: EdgeInsets.only(left: 12, bottom: 10),
  584. width: MediaQuery.of(context).size.width / 4,
  585. height: MediaQuery.of(context).size.width / 4,
  586. child: Image.network(
  587. imageData!,
  588. fit: BoxFit.fill,
  589. ));
  590. }
  591. @override
  592. void dispose() {
  593. super.dispose();
  594. _event.cancel();
  595. }
  596. }