| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- /// 供水管理相关 API 调用服务
- /// 当前使用 mock 数据,后端 API 就绪后替换为真实请求
- class WaterService {
- WaterService._internal();
- static final WaterService instance = WaterService._internal();
- factory WaterService() => instance;
-
- // ==================== Mock 数据 ====================
-
- /// 实时监测数据列表
- Future<List<MonitorItem>> getMonitorList() async {
- await Future.delayed(const Duration(milliseconds: 800));
- return [
- MonitorItem(
- id: 'M001',
- name: '1号泵站',
- type: MonitorType.pumpStation,
- flow: 120.5,
- pressure: 0.35,
- level: null,
- ph: 7.2,
- turbidity: 0.8,
- chlorine: 0.5,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 2)),
- ),
- MonitorItem(
- id: 'M002',
- name: '2号泵站',
- type: MonitorType.pumpStation,
- flow: 98.3,
- pressure: 0.32,
- level: null,
- ph: 7.1,
- turbidity: 0.6,
- chlorine: 0.45,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 1)),
- ),
- MonitorItem(
- id: 'M003',
- name: '3号泵站',
- type: MonitorType.pumpStation,
- flow: 0,
- pressure: 0,
- level: null,
- ph: 0,
- turbidity: 0,
- chlorine: 0,
- status: DeviceStatus.offline,
- updateTime: DateTime.now().subtract(const Duration(hours: 2)),
- ),
- MonitorItem(
- id: 'M004',
- name: '清水池',
- type: MonitorType.reservoir,
- flow: null,
- pressure: null,
- level: 4.2,
- ph: 7.3,
- turbidity: 0.3,
- chlorine: 0.4,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 5)),
- ),
- MonitorItem(
- id: 'M005',
- name: 'DN300主干管',
- type: MonitorType.pipeline,
- flow: 285.6,
- pressure: 0.28,
- level: null,
- ph: null,
- turbidity: null,
- chlorine: null,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 3)),
- ),
- MonitorItem(
- id: 'M006',
- name: 'DN200分支管-A区',
- type: MonitorType.pipeline,
- flow: 86.2,
- pressure: 0.22,
- level: null,
- ph: null,
- turbidity: null,
- chlorine: null,
- status: DeviceStatus.warning,
- updateTime: DateTime.now().subtract(const Duration(minutes: 1)),
- ),
- MonitorItem(
- id: 'M007',
- name: '末梢水质监测点-1',
- type: MonitorType.quality,
- flow: null,
- pressure: 0.15,
- level: null,
- ph: 7.0,
- turbidity: 0.5,
- chlorine: 0.3,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 10)),
- ),
- MonitorItem(
- id: 'M008',
- name: '加药间',
- type: MonitorType.dosing,
- flow: null,
- pressure: null,
- level: 2.8,
- ph: null,
- turbidity: null,
- chlorine: null,
- status: DeviceStatus.online,
- updateTime: DateTime.now().subtract(const Duration(minutes: 8)),
- ),
- ];
- }
-
- /// 报警列表
- Future<List<AlertItem>> getAlertList({bool unreadOnly = false}) async {
- await Future.delayed(const Duration(milliseconds: 600));
- final alerts = [
- AlertItem(
- id: 'A001',
- level: AlertLevel.critical,
- title: '3号泵站设备离线',
- content: '3号泵站PLC控制器通信中断,已持续2小时,请尽快安排人员现场检查。',
- location: '3号泵站',
- deviceName: '3号泵站PLC',
- isRead: false,
- createTime: DateTime.now().subtract(const Duration(hours: 2)),
- handlerName: '待处理',
- ),
- AlertItem(
- id: 'A002',
- level: AlertLevel.warning,
- title: 'DN200分支管压力偏低',
- content: 'A区DN200分支管压力0.22MPa,低于下限0.25MPa,可能存在泄漏或用水量激增。',
- location: 'A区DN200分支管',
- deviceName: '压力传感器-P205',
- isRead: false,
- createTime: DateTime.now().subtract(const Duration(hours: 1)),
- handlerName: '待处理',
- ),
- AlertItem(
- id: 'A003',
- level: AlertLevel.warning,
- title: '清水池液位接近上限',
- content: '清水池液位4.2m,接近上限4.5m,建议减少进水量或增加供水。',
- location: '清水池',
- deviceName: '液位传感器-L001',
- isRead: false,
- createTime: DateTime.now().subtract(const Duration(minutes: 30)),
- handlerName: '待处理',
- ),
- AlertItem(
- id: 'A004',
- level: AlertLevel.info,
- title: '1号泵站例行维护提醒',
- content: '1号泵站运行时间已达5000小时,建议安排例行保养。',
- location: '1号泵站',
- deviceName: '1号泵站主控',
- isRead: true,
- createTime: DateTime.now().subtract(const Duration(hours: 5)),
- handlerName: '王工',
- ),
- AlertItem(
- id: 'A005',
- level: AlertLevel.critical,
- title: '出厂水余氯超标',
- content: '出厂水余氯0.8mg/L,超过国标上限0.8mg/L,请立即调整加药量。',
- location: '水厂出水口',
- deviceName: '水质分析仪-WQ001',
- isRead: true,
- createTime: DateTime.now().subtract(const Duration(hours: 8)),
- handlerName: '李工',
- ),
- AlertItem(
- id: 'A006',
- level: AlertLevel.info,
- title: '2号泵站变频器固件更新',
- content: '2号泵站变频器有新固件版本可用(v2.3.1),建议在下次停机时更新。',
- location: '2号泵站',
- deviceName: '2号变频器',
- isRead: true,
- createTime: DateTime.now().subtract(const Duration(days: 1)),
- handlerName: '系统',
- ),
- ];
- if (unreadOnly) {
- return alerts.where((a) => !a.isRead).toList();
- }
- return alerts;
- }
-
- /// 标记报警为已读
- Future<void> markAlertRead(String alertId) async {
- await Future.delayed(const Duration(milliseconds: 300));
- }
-
- /// 标记所有报警为已读
- Future<void> markAllAlertsRead() async {
- await Future.delayed(const Duration(milliseconds: 500));
- }
-
- /// 今日值班信息
- Future<DutyInfo> getTodayDuty() async {
- await Future.delayed(const Duration(milliseconds: 700));
- return DutyInfo(
- date: DateTime.now(),
- shiftName: '白班',
- shiftTime: '08:00 - 20:00',
- leader: DutyPerson(name: '张建国', phone: '13800138001', role: '值班长'),
- members: [
- DutyPerson(name: '李明', phone: '13800138002', role: '泵站巡检'),
- DutyPerson(name: '王芳', phone: '13800138003', role: '水质监测'),
- DutyPerson(name: '赵强', phone: '13800138004', role: '管网维护'),
- DutyPerson(name: '刘伟', phone: '13800138005', role: '应急抢修'),
- ],
- instructions: [
- DutyInstruction(
- id: 'DI001',
- title: '清水池液位监控',
- content: '密切关注清水池液位,若超过4.5m立即报告并减少进水量。',
- time: '08:30',
- issuer: '调度中心-陈主任',
- status: InstructionStatus.active,
- ),
- DutyInstruction(
- id: 'DI002',
- title: '3号泵站故障排查',
- content: '3号泵站PLC离线,安排刘伟前往现场检查,预计14:00前恢复。',
- time: '09:15',
- issuer: '调度中心-陈主任',
- status: InstructionStatus.inProgress,
- ),
- DutyInstruction(
- id: 'DI003',
- title: 'A区压力监测',
- content: 'A区DN200分支管压力偏低,赵强每30分钟上报一次压力数据。',
- time: '10:00',
- issuer: '调度中心-陈主任',
- status: InstructionStatus.active,
- ),
- DutyInstruction(
- id: 'DI004',
- title: '出厂水余氯检测',
- content: '每小时对出厂水进行一次余氯检测,确保在0.3-0.8mg/L范围内。',
- time: '08:00',
- issuer: '水厂-周厂长',
- status: InstructionStatus.completed,
- ),
- ],
- );
- }
-
- /// 水质数据
- Future<List<QualitySample>> getQualityData() async {
- await Future.delayed(const Duration(milliseconds: 900));
- return [
- QualitySample(
- id: 'Q001',
- category: QualityCategory.rawWater,
- source: '水源地取水口',
- sampleTime: DateTime.now().subtract(const Duration(hours: 1)),
- ph: 7.5,
- turbidity: 12.3,
- color: 15,
- odor: '无异味',
- ammonia: 0.3,
- permanganate: 3.2,
- totalColiform: 280,
- isCompliant: true,
- ),
- QualitySample(
- id: 'Q002',
- category: QualityCategory.factoryWater,
- source: '水厂出水口',
- sampleTime: DateTime.now().subtract(const Duration(hours: 1)),
- ph: 7.2,
- turbidity: 0.3,
- color: 2,
- odor: '无异味',
- ammonia: 0.05,
- permanganate: 1.8,
- totalColiform: 0,
- isCompliant: true,
- ),
- QualitySample(
- id: 'Q003',
- category: QualityCategory.factoryWater,
- source: '清水池出水',
- sampleTime: DateTime.now().subtract(const Duration(hours: 2)),
- ph: 7.1,
- turbidity: 0.4,
- color: 3,
- odor: '无异味',
- ammonia: 0.08,
- permanganate: 2.0,
- totalColiform: 0,
- isCompliant: true,
- ),
- QualitySample(
- id: 'Q004',
- category: QualityCategory.endWater,
- source: 'A区末梢-学校',
- sampleTime: DateTime.now().subtract(const Duration(hours: 3)),
- ph: 7.0,
- turbidity: 0.6,
- color: 4,
- odor: '无异味',
- ammonia: 0.1,
- permanganate: 2.5,
- totalColiform: 0,
- isCompliant: true,
- ),
- QualitySample(
- id: 'Q005',
- category: QualityCategory.endWater,
- source: 'B区末梢-医院',
- sampleTime: DateTime.now().subtract(const Duration(hours: 3)),
- ph: 6.8,
- turbidity: 1.2,
- color: 6,
- odor: '轻微氯味',
- ammonia: 0.15,
- permanganate: 3.0,
- totalColiform: 2,
- isCompliant: false,
- ),
- QualitySample(
- id: 'Q006',
- category: QualityCategory.endWater,
- source: 'C区末梢-居民区',
- sampleTime: DateTime.now().subtract(const Duration(hours: 4)),
- ph: 7.1,
- turbidity: 0.5,
- color: 3,
- odor: '无异味',
- ammonia: 0.08,
- permanganate: 2.2,
- totalColiform: 0,
- isCompliant: true,
- ),
- ];
- }
- }
-
- // ==================== 数据模型 ====================
-
- /// 监测类型
- enum MonitorType {
- pumpStation('泵站'),
- reservoir('水池/水箱'),
- pipeline('管网'),
- quality('水质监测点'),
- dosing('加药间');
-
- final String label;
- const MonitorType(this.label);
- }
-
- /// 设备状态
- enum DeviceStatus {
- online('在线', Color(0xFF4CAF50)),
- offline('离线', Color(0xFF9E9E9E)),
- warning('告警', Color(0xFFFF9800)),
- error('故障', Color(0xFFF44336));
-
- final String label;
- final int color;
- const DeviceStatus(this.label, this.color);
- }
-
- /// 监测数据项
- class MonitorItem {
- final String id;
- final String name;
- final MonitorType type;
- final double? flow; // 流量 m³/h
- final double? pressure; // 压力 MPa
- final double? level; // 液位 m
- final double? ph;
- final double? turbidity; // 浊度 NTU
- final double? chlorine; // 余氯 mg/L
- final DeviceStatus status;
- final DateTime updateTime;
-
- const MonitorItem({
- required this.id,
- required this.name,
- required this.type,
- this.flow,
- this.pressure,
- this.level,
- this.ph,
- this.turbidity,
- this.chlorine,
- required this.status,
- required this.updateTime,
- });
-
- String get statusLabel => status.label;
- }
-
- /// 报警级别
- enum AlertLevel {
- critical('严重', Color(0xFFF44336)),
- warning('警告', Color(0xFFFF9800)),
- info('提示', Color(0xFF2196F3));
-
- final String label;
- final int color;
- const AlertLevel(this.label, this.color);
- }
-
- /// 报警项
- class AlertItem {
- final String id;
- final AlertLevel level;
- final String title;
- final String content;
- final String location;
- final String deviceName;
- bool isRead;
- final DateTime createTime;
- final String handlerName;
-
- AlertItem({
- required this.id,
- required this.level,
- required this.title,
- required this.content,
- required this.location,
- required this.deviceName,
- required this.isRead,
- required this.createTime,
- required this.handlerName,
- });
- }
-
- /// 值班人员
- class DutyPerson {
- final String name;
- final String phone;
- final String role;
-
- const DutyPerson({
- required this.name,
- required this.phone,
- required this.role,
- });
- }
-
- /// 指令状态
- enum InstructionStatus {
- active('待执行', Color(0xFFFF9800)),
- inProgress('执行中', Color(0xFF2196F3)),
- completed('已完成', Color(0xFF4CAF50));
-
- final String label;
- final int color;
- const InstructionStatus(this.label, this.color);
- }
-
- /// 调度指令
- class DutyInstruction {
- final String id;
- final String title;
- final String content;
- final String time;
- final String issuer;
- final InstructionStatus status;
-
- const DutyInstruction({
- required this.id,
- required this.title,
- required this.content,
- required this.time,
- required this.issuer,
- required this.status,
- });
- }
-
- /// 今日值班信息
- class DutyInfo {
- final DateTime date;
- final String shiftName;
- final String shiftTime;
- final DutyPerson leader;
- final List<DutyPerson> members;
- final List<DutyInstruction> instructions;
-
- const DutyInfo({
- required this.date,
- required this.shiftName,
- required this.shiftTime,
- required this.leader,
- required this.members,
- required this.instructions,
- });
- }
-
- /// 水质类别
- enum QualityCategory {
- rawWater('原水'),
- factoryWater('出厂水'),
- endWater('末梢水');
-
- final String label;
- const QualityCategory(this.label);
- }
-
- /// 水质采样数据
- class QualitySample {
- final String id;
- final QualityCategory category;
- final String source;
- final DateTime sampleTime;
- final double ph;
- final double turbidity; // NTU
- final int color; // 色度
- final String odor; // 嗅味
- final double ammonia; // 氨氮 mg/L
- final double permanganate; // 高锰酸盐指数 mg/L
- final int totalColiform; // 总大肠菌群 CFU/100mL
- final bool isCompliant;
-
- const QualitySample({
- required this.id,
- required this.category,
- required this.source,
- required this.sampleTime,
- required this.ph,
- required this.turbidity,
- required this.color,
- required this.odor,
- required this.ammonia,
- required this.permanganate,
- required this.totalColiform,
- required this.isCompliant,
- });
-
- /// 获取各指标达标情况
- List<QualityIndicator> getIndicators() {
- return [
- QualityIndicator('pH', ph.toStringAsFixed(1), '6.5-8.5', ph >= 6.5 && ph <= 8.5),
- QualityIndicator('浊度', '${turbidity.toStringAsFixed(1)} NTU', '≤1 NTU', turbidity <= 1.0),
- QualityIndicator('色度', '$color 度', '≤15 度', color <= 15),
- QualityIndicator('嗅味', odor, '无异味', odor == '无异味'),
- QualityIndicator('氨氮', '${ammonia.toStringAsFixed(2)} mg/L', '≤0.5 mg/L', ammonia <= 0.5),
- QualityIndicator('高锰酸盐', '${permanganate.toStringAsFixed(1)} mg/L', '≤3 mg/L',
- category == QualityCategory.rawWater ? true : permanganate <= 3.0),
- QualityIndicator('总大肠菌群', '$totalColiform CFU/100mL',
- category == QualityCategory.rawWater ? '≤1000' : '不得检出',
- category == QualityCategory.rawWater ? totalColiform <= 1000 : totalColiform == 0),
- ];
- }
- }
-
- /// 水质指标
- class QualityIndicator {
- final String name;
- final String value;
- final String standard;
- final bool isCompliant;
-
- const QualityIndicator(this.name, this.value, this.standard, this.isCompliant);
- }
|