patrol_job_detail.dart 23 KB

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