智慧水务管理系统 - 精河县供水工程综合管理平台

patrol_service.dart 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /// 巡检管理相关 API 调用服务
  2. /// 当前使用 mock 数据,后端 API 就绪后替换为真实请求
  3. class PatrolService {
  4. PatrolService._internal();
  5. static final PatrolService instance = PatrolService._internal();
  6. factory PatrolService() => instance;
  7. // ==================== Mock 数据 ====================
  8. /// 获取巡检任务列表
  9. Future<List<PatrolTask>> getTaskList({PatrolTaskStatus? status}) async {
  10. await Future.delayed(const Duration(milliseconds: 800));
  11. final tasks = [
  12. PatrolTask(
  13. id: 'XJ-2024-001',
  14. routeName: '城东片区巡检路线',
  15. date: DateTime(2024, 6, 14),
  16. totalPoints: 8,
  17. completedPoints: 0,
  18. priority: PatrolPriority.high,
  19. status: PatrolTaskStatus.pending,
  20. assignee: '张建国',
  21. description: '城东片区主干管网及加压站设备巡检,包含8个巡检点',
  22. points: _mockPointsEast,
  23. ),
  24. PatrolTask(
  25. id: 'XJ-2024-002',
  26. routeName: '城北加压站巡检',
  27. date: DateTime(2024, 6, 14),
  28. totalPoints: 4,
  29. completedPoints: 0,
  30. priority: PatrolPriority.medium,
  31. status: PatrolTaskStatus.pending,
  32. assignee: '李明',
  33. description: '城北加压站设备日检,包含泵站、配电柜、压力表等设备',
  34. points: _mockPointsNorth,
  35. ),
  36. PatrolTask(
  37. id: 'XJ-2024-003',
  38. routeName: '水厂设备日检',
  39. date: DateTime(2024, 6, 15),
  40. totalPoints: 12,
  41. completedPoints: 0,
  42. priority: PatrolPriority.high,
  43. status: PatrolTaskStatus.pending,
  44. assignee: '王芳',
  45. description: '水厂全部设备日检,包含取水泵房、净水设备、加药间、消毒间等',
  46. points: _mockPointsFactory,
  47. ),
  48. PatrolTask(
  49. id: 'XJ-2024-004',
  50. routeName: '城西管网巡检',
  51. date: DateTime(2024, 6, 14),
  52. totalPoints: 6,
  53. completedPoints: 3,
  54. priority: PatrolPriority.medium,
  55. status: PatrolTaskStatus.ongoing,
  56. assignee: '赵强',
  57. description: '城西片区管网巡检,重点检查阀门井和消防栓',
  58. points: _mockPointsWest,
  59. ),
  60. PatrolTask(
  61. id: 'XJ-2024-005',
  62. routeName: '城南片区周检',
  63. date: DateTime(2024, 6, 13),
  64. totalPoints: 10,
  65. completedPoints: 10,
  66. priority: PatrolPriority.low,
  67. status: PatrolTaskStatus.completed,
  68. assignee: '刘伟',
  69. description: '城南片区管网周检',
  70. points: _mockPointsSouth,
  71. result: PatrolResult.normal,
  72. reportTime: DateTime(2024, 6, 13, 16, 30),
  73. ),
  74. PatrolTask(
  75. id: 'XJ-2024-006',
  76. routeName: '水厂设备周检',
  77. date: DateTime(2024, 6, 13),
  78. totalPoints: 12,
  79. completedPoints: 12,
  80. priority: PatrolPriority.high,
  81. status: PatrolTaskStatus.completed,
  82. assignee: '张建国',
  83. description: '水厂全部设备周检',
  84. points: _mockPointsFactory,
  85. result: PatrolResult.issueFound,
  86. reportTime: DateTime(2024, 6, 13, 15, 0),
  87. issues: '2号加药泵存在异响,已记录待维修',
  88. ),
  89. ];
  90. if (status != null) {
  91. return tasks.where((t) => t.status == status).toList();
  92. }
  93. return tasks;
  94. }
  95. /// 获取任务详情
  96. Future<PatrolTask?> getTaskDetail(String taskId) async {
  97. await Future.delayed(const Duration(milliseconds: 500));
  98. final tasks = await getTaskList();
  99. try {
  100. return tasks.firstWhere((t) => t.id == taskId);
  101. } catch (_) {
  102. return null;
  103. }
  104. }
  105. /// 开始巡检任务
  106. Future<bool> startTask(String taskId) async {
  107. await Future.delayed(const Duration(milliseconds: 600));
  108. return true;
  109. }
  110. /// 提交巡检点上报
  111. Future<bool> submitPointReport({
  112. required String taskId,
  113. required String pointId,
  114. required PatrolPointStatus status,
  115. String? remark,
  116. List<String>? photoPaths,
  117. }) async {
  118. await Future.delayed(const Duration(milliseconds: 700));
  119. return true;
  120. }
  121. /// 完成巡检任务
  122. Future<bool> completeTask({
  123. required String taskId,
  124. required PatrolResult result,
  125. String? summary,
  126. }) async {
  127. await Future.delayed(const Duration(milliseconds: 800));
  128. return true;
  129. }
  130. /// 获取GPS轨迹点列表
  131. Future<List<TrackPoint>> getTrackPoints(String taskId) async {
  132. await Future.delayed(const Duration(milliseconds: 500));
  133. return [
  134. TrackPoint(
  135. id: 'TP001',
  136. lat: 30.2741,
  137. lng: 120.1551,
  138. altitude: 15.2,
  139. speed: 0,
  140. timestamp: DateTime(2024, 6, 14, 8, 0),
  141. address: '水厂大门',
  142. ),
  143. TrackPoint(
  144. id: 'TP002',
  145. lat: 30.2748,
  146. lng: 120.1562,
  147. altitude: 14.8,
  148. speed: 3.2,
  149. timestamp: DateTime(2024, 6, 14, 8, 5),
  150. address: '城东路段阀门井',
  151. ),
  152. TrackPoint(
  153. id: 'TP003',
  154. lat: 30.2755,
  155. lng: 120.1578,
  156. altitude: 15.0,
  157. speed: 2.8,
  158. timestamp: DateTime(2024, 6, 14, 8, 12),
  159. address: '阳光小区加压站',
  160. ),
  161. TrackPoint(
  162. id: 'TP004',
  163. lat: 30.2763,
  164. lng: 120.1590,
  165. altitude: 14.5,
  166. speed: 0,
  167. timestamp: DateTime(2024, 6, 14, 8, 20),
  168. address: '城东消防栓-03',
  169. ),
  170. TrackPoint(
  171. id: 'TP005',
  172. lat: 30.2770,
  173. lng: 120.1605,
  174. altitude: 15.3,
  175. speed: 4.1,
  176. timestamp: DateTime(2024, 6, 14, 8, 28),
  177. address: '东方名城阀门井',
  178. ),
  179. TrackPoint(
  180. id: 'TP006',
  181. lat: 30.2778,
  182. lng: 120.1618,
  183. altitude: 14.9,
  184. speed: 0,
  185. timestamp: DateTime(2024, 6, 14, 8, 35),
  186. address: '城东片区末端压力表',
  187. ),
  188. ];
  189. }
  190. // ==================== Mock 巡检点数据 ====================
  191. static final List<PatrolPoint> _mockPointsEast = [
  192. PatrolPoint(id: 'PP001', name: '城东路段阀门井', type: PatrolPointType.valve, lat: 30.2748, lng: 120.1562, order: 1),
  193. PatrolPoint(id: 'PP002', name: '阳光小区加压站', type: PatrolPointType.pumpStation, lat: 30.2755, lng: 120.1578, order: 2),
  194. PatrolPoint(id: 'PP003', name: '城东消防栓-03', type: PatrolPointType.hydrant, lat: 30.2763, lng: 120.1590, order: 3),
  195. PatrolPoint(id: 'PP004', name: '东方名城阀门井', type: PatrolPointType.valve, lat: 30.2770, lng: 120.1605, order: 4),
  196. PatrolPoint(id: 'PP005', name: '城东片区末端压力表', type: PatrolPointType.meter, lat: 30.2778, lng: 120.1618, order: 5),
  197. PatrolPoint(id: 'PP006', name: '锦绣家园管网接口', type: PatrolPointType.junction, lat: 30.2785, lng: 120.1630, order: 6),
  198. PatrolPoint(id: 'PP007', name: '翠湖路排气阀', type: PatrolPointType.valve, lat: 30.2792, lng: 120.1645, order: 7),
  199. PatrolPoint(id: 'PP008', name: '城东片区测流点', type: PatrolPointType.meter, lat: 30.2800, lng: 120.1660, order: 8),
  200. ];
  201. static final List<PatrolPoint> _mockPointsNorth = [
  202. PatrolPoint(id: 'PP009', name: '城北加压站1号泵', type: PatrolPointType.pumpStation, lat: 30.2900, lng: 120.1500, order: 1),
  203. PatrolPoint(id: 'PP010', name: '城北加压站配电柜', type: PatrolPointType.electrical, lat: 30.2902, lng: 120.1505, order: 2),
  204. PatrolPoint(id: 'PP011', name: '城北加压站出水压力表', type: PatrolPointType.meter, lat: 30.2905, lng: 120.1510, order: 3),
  205. PatrolPoint(id: 'PP012', name: '城北加压站流量计', type: PatrolPointType.meter, lat: 30.2908, lng: 120.1515, order: 4),
  206. ];
  207. static final List<PatrolPoint> _mockPointsFactory = [
  208. PatrolPoint(id: 'PP013', name: '取水泵房', type: PatrolPointType.pumpStation, lat: 30.2700, lng: 120.1400, order: 1),
  209. PatrolPoint(id: 'PP014', name: '混合池', type: PatrolPointType.equipment, lat: 30.2705, lng: 120.1410, order: 2),
  210. PatrolPoint(id: 'PP015', name: '絮凝池', type: PatrolPointType.equipment, lat: 30.2710, lng: 120.1420, order: 3),
  211. PatrolPoint(id: 'PP016', name: '沉淀池', type: PatrolPointType.equipment, lat: 30.2715, lng: 120.1430, order: 4),
  212. PatrolPoint(id: 'PP017', name: '滤池-1号', type: PatrolPointType.equipment, lat: 30.2720, lng: 120.1440, order: 5),
  213. PatrolPoint(id: 'PP018', name: '滤池-2号', type: PatrolPointType.equipment, lat: 30.2722, lng: 120.1445, order: 6),
  214. PatrolPoint(id: 'PP019', name: '清水池', type: PatrolPointType.reservoir, lat: 30.2725, lng: 120.1450, order: 7),
  215. PatrolPoint(id: 'PP020', name: '加药间', type: PatrolPointType.equipment, lat: 30.2728, lng: 120.1455, order: 8),
  216. PatrolPoint(id: 'PP021', name: '消毒间', type: PatrolPointType.equipment, lat: 30.2730, lng: 120.1460, order: 9),
  217. PatrolPoint(id: 'PP022', name: '送水泵房', type: PatrolPointType.pumpStation, lat: 30.2733, lng: 120.1465, order: 10),
  218. PatrolPoint(id: 'PP023', name: '出厂水水质仪', type: PatrolPointType.meter, lat: 30.2735, lng: 120.1470, order: 11),
  219. PatrolPoint(id: 'PP024', name: '出水流量计', type: PatrolPointType.meter, lat: 30.2738, lng: 120.1475, order: 12),
  220. ];
  221. static final List<PatrolPoint> _mockPointsWest = [
  222. PatrolPoint(id: 'PP025', name: '城西阀门井-01', type: PatrolPointType.valve, lat: 30.2750, lng: 120.1450, order: 1),
  223. PatrolPoint(id: 'PP026', name: '城西消防栓-01', type: PatrolPointType.hydrant, lat: 30.2758, lng: 120.1438, order: 2),
  224. PatrolPoint(id: 'PP027', name: '翠湖花园加压站', type: PatrolPointType.pumpStation, lat: 30.2765, lng: 120.1425, order: 3),
  225. PatrolPoint(id: 'PP028', name: '城西排气阀', type: PatrolPointType.valve, lat: 30.2772, lng: 120.1412, order: 4),
  226. PatrolPoint(id: 'PP029', name: '城西测流点', type: PatrolPointType.meter, lat: 30.2780, lng: 120.1400, order: 5),
  227. PatrolPoint(id: 'PP030', name: '城西末端压力表', type: PatrolPointType.meter, lat: 30.2788, lng: 120.1388, order: 6),
  228. ];
  229. static final List<PatrolPoint> _mockPointsSouth = [
  230. PatrolPoint(id: 'PP031', name: '城南阀门井-01', type: PatrolPointType.valve, lat: 30.2650, lng: 120.1520, order: 1),
  231. PatrolPoint(id: 'PP032', name: '城南加压站', type: PatrolPointType.pumpStation, lat: 30.2640, lng: 120.1530, order: 2),
  232. PatrolPoint(id: 'PP033', name: '阳光小区消防栓', type: PatrolPointType.hydrant, lat: 30.2630, lng: 120.1540, order: 3),
  233. PatrolPoint(id: 'PP034', name: '城南排气阀', type: PatrolPointType.valve, lat: 30.2620, lng: 120.1550, order: 4),
  234. PatrolPoint(id: 'PP035', name: '城南测流点', type: PatrolPointType.meter, lat: 30.2610, lng: 120.1560, order: 5),
  235. PatrolPoint(id: 'PP036', name: '学校管网接口', type: PatrolPointType.junction, lat: 30.2600, lng: 120.1570, order: 6),
  236. PatrolPoint(id: 'PP037', name: '医院管网接口', type: PatrolPointType.junction, lat: 30.2590, lng: 120.1580, order: 7),
  237. PatrolPoint(id: 'PP038', name: '城南末端压力表', type: PatrolPointType.meter, lat: 30.2580, lng: 120.1590, order: 8),
  238. PatrolPoint(id: 'PP039', name: '城南消防栓-02', type: PatrolPointType.hydrant, lat: 30.2570, lng: 120.1600, order: 9),
  239. PatrolPoint(id: 'PP040', name: '城南回水阀门', type: PatrolPointType.valve, lat: 30.2560, lng: 120.1610, order: 10),
  240. ];
  241. }
  242. // ==================== 数据模型 ====================
  243. /// 巡检任务状态
  244. enum PatrolTaskStatus {
  245. pending('待执行'),
  246. ongoing('进行中'),
  247. completed('已完成');
  248. final String label;
  249. const PatrolTaskStatus(this.label);
  250. }
  251. /// 巡检优先级
  252. enum PatrolPriority {
  253. high('高', 0xFFF44336),
  254. medium('中', 0xFFFF9800),
  255. low('低', 0xFF4CAF50);
  256. final String label;
  257. final int color;
  258. const PatrolPriority(this.label, this.color);
  259. }
  260. /// 巡检结果
  261. enum PatrolResult {
  262. normal('正常'),
  263. issueFound('发现问题');
  264. final String label;
  265. const PatrolResult(this.label);
  266. }
  267. /// 巡检点类型
  268. enum PatrolPointType {
  269. valve('阀门井'),
  270. pumpStation('泵站'),
  271. hydrant('消防栓'),
  272. meter('仪表'),
  273. junction('管网接口'),
  274. electrical('配电柜'),
  275. equipment('设备'),
  276. reservoir('水池');
  277. final String label;
  278. const PatrolPointType(this.label);
  279. }
  280. /// 巡检点状态
  281. enum PatrolPointStatus {
  282. normal('正常'),
  283. abnormal('异常'),
  284. maintenance('需维护');
  285. final String label;
  286. const PatrolPointStatus(this.label);
  287. }
  288. /// 巡检点
  289. class PatrolPoint {
  290. final String id;
  291. final String name;
  292. final PatrolPointType type;
  293. final double lat;
  294. final double lng;
  295. final int order;
  296. PatrolPointStatus? status;
  297. String? remark;
  298. List<String>? photos;
  299. PatrolPoint({
  300. required this.id,
  301. required this.name,
  302. required this.type,
  303. required this.lat,
  304. required this.lng,
  305. required this.order,
  306. this.status,
  307. this.remark,
  308. this.photos,
  309. });
  310. }
  311. /// GPS 轨迹点
  312. class TrackPoint {
  313. final String id;
  314. final double lat;
  315. final double lng;
  316. final double altitude;
  317. final double speed;
  318. final DateTime timestamp;
  319. final String address;
  320. const TrackPoint({
  321. required this.id,
  322. required this.lat,
  323. required this.lng,
  324. required this.altitude,
  325. required this.speed,
  326. required this.timestamp,
  327. required this.address,
  328. });
  329. }
  330. /// 巡检任务
  331. class PatrolTask {
  332. final String id;
  333. final String routeName;
  334. final DateTime date;
  335. final int totalPoints;
  336. final int completedPoints;
  337. final PatrolPriority priority;
  338. final PatrolTaskStatus status;
  339. final String assignee;
  340. final String description;
  341. final List<PatrolPoint> points;
  342. final PatrolResult? result;
  343. final DateTime? reportTime;
  344. final String? issues;
  345. const PatrolTask({
  346. required this.id,
  347. required this.routeName,
  348. required this.date,
  349. required this.totalPoints,
  350. required this.completedPoints,
  351. required this.priority,
  352. required this.status,
  353. required this.assignee,
  354. required this.description,
  355. required this.points,
  356. this.result,
  357. this.reportTime,
  358. this.issues,
  359. });
  360. double get progress => totalPoints > 0 ? completedPoints / totalPoints : 0;
  361. String get dateStr =>
  362. '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
  363. }