Commit c7d9fb26 authored by 张宏's avatar 张宏

http移动

parent 76a57f12
...@@ -7,7 +7,7 @@ import 'package:smart_hotel_app/blocs/auth/auth_state.dart'; ...@@ -7,7 +7,7 @@ import 'package:smart_hotel_app/blocs/auth/auth_state.dart';
import 'package:smart_hotel_app/routes/app_router.dart'; import 'package:smart_hotel_app/routes/app_router.dart';
import 'package:smart_hotel_app/repositories/auth_repository.dart'; import 'package:smart_hotel_app/repositories/auth_repository.dart';
import 'package:smart_hotel_app/services/auth_service.dart'; import 'package:smart_hotel_app/services/auth_service.dart';
import 'package:smart_hotel_app/http/dio_request.dart'; import 'package:smart_hotel_app/utils/http/dio_request.dart';
import 'package:smart_hotel_app/utils/event_bus.dart'; import 'package:smart_hotel_app/utils/event_bus.dart';
import 'package:smart_hotel_app/utils/storage/storage_service.dart'; import 'package:smart_hotel_app/utils/storage/storage_service.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart'; import 'package:smart_hotel_app/routes/app_router.gr.dart';
......
import '../http/response_model.dart'; import '../utils/http/response_model.dart';
import '../http/dio_request.dart'; import '../utils/http/dio_request.dart';
class AuthRepository { class AuthRepository {
Future<ResponseModel> login(Map<String, dynamic> params) { Future<ResponseModel> login(Map<String, dynamic> params) {
......
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import '../utils/constants.dart'; import '../constants.dart';
import 'exceptions/app_exception.dart'; import 'exceptions/app_exception.dart';
import 'interceptors/error_interceptor.dart'; import 'interceptors/error_interceptor.dart';
import 'interceptors/request_interceptor.dart'; import 'interceptors/request_interceptor.dart';
import 'interceptors/response_interceptor.dart'; import 'interceptors/response_interceptor.dart';
import '../utils/storage/storage_service.dart'; import '../storage/storage_service.dart';
import 'response_model.dart'; import 'response_model.dart';
class DioRequest { class DioRequest {
......
import 'dart:io'; import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import '../../utils/event_bus.dart'; import '../../event_bus.dart';
import '../exceptions/app_exception.dart'; import '../exceptions/app_exception.dart';
import '../exceptions/business_exception.dart'; import '../exceptions/business_exception.dart';
import '../exceptions/cancel_exception.dart'; import '../exceptions/cancel_exception.dart';
......
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import '../../utils/storage/storage_service.dart'; import '../../storage/storage_service.dart';
class RequestInterceptor extends Interceptor { class RequestInterceptor extends Interceptor {
final StorageService _storageService; final StorageService _storageService;
......
# 智慧酒店 App 接口对接方案 # 智慧酒店 App 接口对接方案
...@@ -121,26 +121,17 @@ class XxxCubit extends Cubit<XxxState> { ...@@ -121,26 +121,17 @@ class XxxCubit extends Cubit<XxxState> {
### 2.1 文件清单 ### 2.1 文件清单
按模块组织,每个文件包含该模块所有 BO 类 按模块组织,每个文件包含该模块所有 BO 类,每个 BO 类对应一个 State 类,并且继承 `Equatable`
| 文件 | 包含的 BO 类 | 对应原 State 文件中的类 |
|------|-------------|----------------------|
| `alarm_bo.dart` | `AlarmItemBO`, `AlarmDetailBO`, `TemperatureSpotBO` | `AlarmItem`, `AlarmInfo` |
| `device_bo.dart` | `DeviceInfoBO`, `EquipmentItemBO` | `DeviceInfo`, `EquipmentItem` |
| `inspection_bo.dart` | `InspectionDeviceBO`, `InspectionRecordBO`, `InspectionItemBO` | `InspectionDevice`, `InspectionRecord` 等 |
| `topology_bo.dart` | `TopologyNodeBO` | `TopologyNode` |
| `energy_bo.dart` | `EnergyOverviewBO`, `ZoneDataBO`, `HourlyDataBO` | `ZoneData` 等 |
| `room_bo.dart` | `RoomInfoBO`, `RoomDeviceBO`, `RoomDeviceStatusBO` | `RoomInfo`, `RoomDevice`, `RoomDeviceStatus` |
| `rule_bo.dart` | `RuleInfoBO` | `RuleInfo` |
### 2.2 详细定义 ### 2.2 定义模版
#### alarm_bo.dart #### xxx_bo.dart
```dart ```dart
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
class AlarmItemBO extends Equatable { class xxxBO extends Equatable {
final String id; final String id;
final String title; final String title;
final String deviceInfo; final String deviceInfo;
...@@ -150,7 +141,7 @@ class AlarmItemBO extends Equatable { ...@@ -150,7 +141,7 @@ class AlarmItemBO extends Equatable {
final String level; // "高警" | "中警" | "低警" final String level; // "高警" | "中警" | "低警"
final String urgency; // "紧急" | "一般" final String urgency; // "紧急" | "一般"
const AlarmItemBO({ const xxxBO({
required this.id, required this.id,
required this.title, required this.title,
required this.deviceInfo, required this.deviceInfo,
...@@ -161,8 +152,8 @@ class AlarmItemBO extends Equatable { ...@@ -161,8 +152,8 @@ class AlarmItemBO extends Equatable {
required this.urgency, required this.urgency,
}); });
factory AlarmItemBO.fromJson(Map<String, dynamic> json) { factory xxxBO.fromJson(Map<String, dynamic> json) {
return AlarmItemBO( return xxxBO(
id: json['id'] as String, id: json['id'] as String,
title: json['title'] as String, title: json['title'] as String,
deviceInfo: json['deviceInfo'] as String? ?? '', deviceInfo: json['deviceInfo'] as String? ?? '',
...@@ -178,494 +169,8 @@ class AlarmItemBO extends Equatable { ...@@ -178,494 +169,8 @@ class AlarmItemBO extends Equatable {
List<Object?> get props => [id, title, deviceInfo, alarmTime, processTime, status, level, urgency]; List<Object?> get props => [id, title, deviceInfo, alarmTime, processTime, status, level, urgency];
} }
class AlarmDetailBO extends Equatable {
final String alarmType;
final String deviceInfo;
final String alarmLevel;
final String urgency;
final String currentTemp;
final String voltage;
final String current;
final String triggerTime;
final String threshold;
final String duration;
final String peak;
final String linkAction;
final String date;
final List<TemperatureSpotBO> temperatureSpots;
const AlarmDetailBO({
required this.alarmType,
required this.deviceInfo,
required this.alarmLevel,
required this.urgency,
required this.currentTemp,
required this.voltage,
required this.current,
required this.triggerTime,
required this.threshold,
required this.duration,
required this.peak,
required this.linkAction,
required this.date,
required this.temperatureSpots,
});
factory AlarmDetailBO.fromJson(Map<String, dynamic> json) {
return AlarmDetailBO(
alarmType: json['alarmType'] as String? ?? '',
deviceInfo: json['deviceInfo'] as String? ?? '',
alarmLevel: json['alarmLevel'] as String? ?? '',
urgency: json['urgency'] as String? ?? '',
currentTemp: json['currentTemp'] as String? ?? '',
voltage: json['voltage'] as String? ?? '',
current: json['current'] as String? ?? '',
triggerTime: json['triggerTime'] as String? ?? '',
threshold: json['threshold'] as String? ?? '',
duration: json['duration'] as String? ?? '',
peak: json['peak'] as String? ?? '',
linkAction: json['linkAction'] as String? ?? '',
date: json['date'] as String? ?? '',
temperatureSpots: (json['temperatureSpots'] as List<dynamic>?)
?.map((e) => TemperatureSpotBO.fromJson(e as Map<String, dynamic>))
.toList() ?? [],
);
}
@override
List<Object?> get props => [alarmType, deviceInfo, alarmLevel, urgency, currentTemp, voltage, current, triggerTime, threshold, duration, peak, linkAction, date, temperatureSpots];
}
class TemperatureSpotBO extends Equatable {
final double x;
final double y;
const TemperatureSpotBO({required this.x, required this.y});
factory TemperatureSpotBO.fromJson(Map<String, dynamic> json) {
return TemperatureSpotBO(
x: (json['x'] as num).toDouble(),
y: (json['y'] as num).toDouble(),
);
}
@override
List<Object?> get props => [x, y];
}
```
#### device_bo.dart
```dart
import 'package:equatable/equatable.dart';
class DeviceInfoBO extends Equatable {
final String deviceName;
final String deviceId;
final String location;
final String status;
final String voltage;
final String current;
final String power;
final String temperature;
final List<double> powerData;
final List<double> tempData;
const DeviceInfoBO({
required this.deviceName,
required this.deviceId,
required this.location,
required this.status,
required this.voltage,
required this.current,
required this.power,
required this.temperature,
required this.powerData,
required this.tempData,
});
factory DeviceInfoBO.fromJson(Map<String, dynamic> json) {
return DeviceInfoBO(
deviceName: json['deviceName'] as String? ?? '',
deviceId: json['deviceId'] as String? ?? '',
location: json['location'] as String? ?? '',
status: json['status'] as String? ?? '',
voltage: json['voltage'] as String? ?? '',
current: json['current'] as String? ?? '',
power: json['power'] as String? ?? '',
temperature: json['temperature'] as String? ?? '',
powerData: (json['powerData'] as List<dynamic>?)?.map((e) => (e as num).toDouble()).toList() ?? [],
tempData: (json['tempData'] as List<dynamic>?)?.map((e) => (e as num).toDouble()).toList() ?? [],
);
}
@override
List<Object?> get props => [deviceName, deviceId, location, status, voltage, current, power, temperature, powerData, tempData];
}
class EquipmentItemBO extends Equatable {
final String title;
final String subtitle;
final String status;
final String statusColor; // hex color string, e.g. "#1ABC9C"
const EquipmentItemBO({
required this.title,
required this.subtitle,
required this.status,
required this.statusColor,
});
factory EquipmentItemBO.fromJson(Map<String, dynamic> json) {
return EquipmentItemBO(
title: json['title'] as String? ?? '',
subtitle: json['subtitle'] as String? ?? '',
status: json['status'] as String? ?? '',
statusColor: json['statusColor'] as String? ?? '#1ABC9C',
);
}
@override
List<Object?> get props => [title, subtitle, status, statusColor];
}
```
#### inspection_bo.dart
```dart
import 'package:equatable/equatable.dart';
class InspectionDeviceBO extends Equatable {
final String id;
final String name;
final String type;
final String location;
final String status;
final String time;
final String statusColor;
const InspectionDeviceBO({
required this.id,
required this.name,
required this.type,
required this.location,
required this.status,
required this.time,
required this.statusColor,
});
factory InspectionDeviceBO.fromJson(Map<String, dynamic> json) {
return InspectionDeviceBO(
id: json['id'] as String? ?? '',
name: json['name'] as String? ?? '',
type: json['type'] as String? ?? '',
location: json['location'] as String? ?? '',
status: json['status'] as String? ?? '',
time: json['time'] as String? ?? '',
statusColor: json['statusColor'] as String? ?? '#1ABC9C',
);
}
@override
List<Object?> get props => [id, name, type, location, status, time, statusColor];
}
class InspectionRecordBO extends Equatable {
final String deviceName;
final String inspectorName;
final String inspectionTime;
final String result;
final String remark;
final List<InspectionItemBO> items;
const InspectionRecordBO({
required this.deviceName,
required this.inspectorName,
required this.inspectionTime,
required this.result,
required this.remark,
required this.items,
});
factory InspectionRecordBO.fromJson(Map<String, dynamic> json) {
return InspectionRecordBO(
deviceName: json['deviceName'] as String? ?? '',
inspectorName: json['inspectorName'] as String? ?? '',
inspectionTime: json['inspectionTime'] as String? ?? '',
result: json['result'] as String? ?? '',
remark: json['remark'] as String? ?? '',
items: (json['items'] as List<dynamic>?)
?.map((e) => InspectionItemBO.fromJson(e as Map<String, dynamic>))
.toList() ?? [],
);
}
@override
List<Object?> get props => [deviceName, inspectorName, inspectionTime, result, remark, items];
}
class InspectionItemBO extends Equatable {
final String name;
final String status;
final String value;
const InspectionItemBO({
required this.name,
required this.status,
required this.value,
});
factory InspectionItemBO.fromJson(Map<String, dynamic> json) {
return InspectionItemBO(
name: json['name'] as String? ?? '',
status: json['status'] as String? ?? '',
value: json['value'] as String? ?? '',
);
}
@override
List<Object?> get props => [name, status, value];
}
```
#### topology_bo.dart
```dart
import 'package:equatable/equatable.dart';
class TopologyNodeBO extends Equatable {
final String id;
final String name;
final String status;
final List<TopologyNodeBO> children;
final double x;
final double y;
const TopologyNodeBO({
required this.id,
required this.name,
required this.status,
required this.children,
required this.x,
required this.y,
});
factory TopologyNodeBO.fromJson(Map<String, dynamic> json) {
return TopologyNodeBO(
id: json['id'] as String? ?? '',
name: json['name'] as String? ?? '',
status: json['status'] as String? ?? '',
children: (json['children'] as List<dynamic>?)
?.map((e) => TopologyNodeBO.fromJson(e as Map<String, dynamic>))
.toList() ?? [],
x: (json['x'] as num?)?.toDouble() ?? 0,
y: (json['y'] as num?)?.toDouble() ?? 0,
);
}
@override
List<Object?> get props => [id, name, status, children, x, y];
}
```
#### energy_bo.dart
```dart
import 'package:equatable/equatable.dart';
class EnergyOverviewBO extends Equatable {
final double todayEnergy;
final double todayEnergyChange;
final double monthEnergy;
final double monthEnergyChange;
final double monthBill;
final List<double> hourlyData;
final List<ZoneDataBO> zoneData;
const EnergyOverviewBO({
required this.todayEnergy,
required this.todayEnergyChange,
required this.monthEnergy,
required this.monthEnergyChange,
required this.monthBill,
required this.hourlyData,
required this.zoneData,
});
factory EnergyOverviewBO.fromJson(Map<String, dynamic> json) {
return EnergyOverviewBO(
todayEnergy: (json['todayEnergy'] as num?)?.toDouble() ?? 0,
todayEnergyChange: (json['todayEnergyChange'] as num?)?.toDouble() ?? 0,
monthEnergy: (json['monthEnergy'] as num?)?.toDouble() ?? 0,
monthEnergyChange: (json['monthEnergyChange'] as num?)?.toDouble() ?? 0,
monthBill: (json['monthBill'] as num?)?.toDouble() ?? 0,
hourlyData: (json['hourlyData'] as List<dynamic>?)?.map((e) => (e as num).toDouble()).toList() ?? [],
zoneData: (json['zoneData'] as List<dynamic>?)
?.map((e) => ZoneDataBO.fromJson(e as Map<String, dynamic>))
.toList() ?? [],
);
}
@override
List<Object?> get props => [todayEnergy, todayEnergyChange, monthEnergy, monthEnergyChange, monthBill, hourlyData, zoneData];
}
class ZoneDataBO extends Equatable {
final String name;
final double percentage;
final double energy;
const ZoneDataBO({required this.name, required this.percentage, required this.energy});
factory ZoneDataBO.fromJson(Map<String, dynamic> json) {
return ZoneDataBO(
name: json['name'] as String? ?? '',
percentage: (json['percentage'] as num?)?.toDouble() ?? 0,
energy: (json['energy'] as num?)?.toDouble() ?? 0,
);
}
@override
List<Object?> get props => [name, percentage, energy];
}
``` ```
#### room_bo.dart
```dart
import 'package:equatable/equatable.dart';
class RoomBO extends Equatable {
final String roomNumber;
final String status; // "vacant" | "occupied" | "reserved" | "warning" | "temperature"
final String statusText;
final RoomDeviceStatusBO deviceStatus;
const RoomBO({
required this.roomNumber,
required this.status,
required this.statusText,
required this.deviceStatus,
});
factory RoomBO.fromJson(Map<String, dynamic> json) {
return RoomBO(
roomNumber: json['roomNumber'] as String? ?? '',
status: json['status'] as String? ?? 'vacant',
statusText: json['statusText'] as String? ?? '',
deviceStatus: RoomDeviceStatusBO.fromJson(json['deviceStatus'] as Map<String, dynamic>? ?? {}),
);
}
@override
List<Object?> get props => [roomNumber, status, statusText, deviceStatus];
}
class RoomDeviceStatusBO extends Equatable {
final bool hasPerson;
final bool powerOn;
final bool wifiNormal;
final bool acOn;
final String acTemperature;
final bool lightOn;
final bool tvOn;
final bool curtainOn;
const RoomDeviceStatusBO({
this.hasPerson = true,
this.powerOn = true,
this.wifiNormal = true,
this.acOn = false,
this.acTemperature = '24',
this.lightOn = false,
this.tvOn = false,
this.curtainOn = false,
});
factory RoomDeviceStatusBO.fromJson(Map<String, dynamic> json) {
return RoomDeviceStatusBO(
hasPerson: json['hasPerson'] as bool? ?? true,
powerOn: json['powerOn'] as bool? ?? true,
wifiNormal: json['wifiNormal'] as bool? ?? true,
acOn: json['acOn'] as bool? ?? false,
acTemperature: json['acTemperature'] as String? ?? '24',
lightOn: json['lightOn'] as bool? ?? false,
tvOn: json['tvOn'] as bool? ?? false,
curtainOn: json['curtainOn'] as bool? ?? false,
);
}
@override
List<Object?> get props => [hasPerson, powerOn, wifiNormal, acOn, acTemperature, lightOn, tvOn, curtainOn];
}
class RoomDeviceBO extends Equatable {
final String name;
final String iconType; // "power" | "ac" | "light" | "tv" | "curtain" | "wifi"
final bool isOn;
final String? statusText;
const RoomDeviceBO({
required this.name,
required this.iconType,
this.isOn = false,
this.statusText,
});
factory RoomDeviceBO.fromJson(Map<String, dynamic> json) {
return RoomDeviceBO(
name: json['name'] as String? ?? '',
iconType: json['iconType'] as String? ?? 'power',
isOn: json['isOn'] as bool? ?? false,
statusText: json['statusText'] as String?,
);
}
@override
List<Object?> get props => [name, iconType, isOn, statusText];
}
```
#### rule_bo.dart
```dart
import 'package:equatable/equatable.dart';
class RuleBO extends Equatable {
final String id;
final String name;
final String description;
final bool enabled;
final String triggerCondition;
final String action;
final String iconType; // "thermostat" | "power" | "schedule" | ...
const RuleBO({
required this.id,
required this.name,
required this.description,
required this.enabled,
required this.triggerCondition,
required this.action,
required this.iconType,
});
factory RuleBO.fromJson(Map<String, dynamic> json) {
return RuleBO(
id: json['id'] as String? ?? '',
name: json['name'] as String? ?? '',
description: json['description'] as String? ?? '',
enabled: json['enabled'] as bool? ?? false,
triggerCondition: json['triggerCondition'] as String? ?? '',
action: json['action'] as String? ?? '',
iconType: json['iconType'] as String? ?? 'power',
);
}
@override
List<Object?> get props => [id, name, description, enabled, triggerCondition, action, iconType];
}
```
--- ---
...@@ -675,33 +180,13 @@ class RuleBO extends Equatable { ...@@ -675,33 +180,13 @@ class RuleBO extends Equatable {
| 序号 | 方法 | 路径 | 说明 | 所属模块 | | 序号 | 方法 | 路径 | 说明 | 所属模块 |
|------|------|------|------|---------| |------|------|------|------|---------|
| 1 | POST | `/api/login` | 登录 | 认证 |
| 2 | GET | `/api/user/profile` | 获取用户信息 | 个人中心 |
| 3 | POST | `/api/logout` | 退出登录 | 认证 |
| 4 | GET | `/api/alarms` | 告警列表 | 告警 |
| 5 | GET | `/api/alarms/{id}` | 告警详情 | 告警 |
| 6 | GET | `/api/home/overview` | 告警首页概览 | 告警 |
| 7 | GET | `/api/devices/{id}` | 设备详情 | 告警 |
| 8 | GET | `/api/inspections` | 巡检任务列表 | 巡检 |
| 9 | GET | `/api/inspections/{id}/devices` | 巡检设备列表 | 巡检 |
| 10 | GET | `/api/inspections/devices/{id}/detail` | 巡检设备详情 | 巡检 |
| 11 | GET | `/api/inspections/devices/{id}/history` | 巡检历史 | 巡检 |
| 12 | GET | `/api/inspections/{id}/topology` | 巡检拓扑 | 巡检 |
| 13 | GET | `/api/service/overview` | 管理首页概览 | 管理 |
| 14 | GET | `/api/service/rooms` | 房间列表 | 管理 |
| 15 | GET | `/api/service/rooms/{roomNumber}` | 房间详情 | 管理 |
| 16 | POST | `/api/service/rooms/{roomNumber}/devices/control` | 设备控制 | 管理 |
| 17 | GET | `/api/reports/overview` | 能耗总览 | 能耗 |
| 18 | GET | `/api/reports/devices` | 设备能耗列表 | 能耗 |
| 19 | GET | `/api/reports/devices/{id}` | 设备能耗详情 | 能耗 |
| 20 | GET | `/api/reports/energy` | 区域能耗 | 能耗 |
| 21 | GET | `/api/reports/rooms` | 房间能耗报告 | 能耗 |
| 22 | GET | `/api/reports/rules` | 规则列表 | 能耗 |
| 23 | POST | `/api/reports/rules/{id}/toggle` | 规则开关 | 能耗 |
### 3.2 接口详细定义 ### 3.2 接口详细定义
#### 认证模块 #### 模版
**POST /api/login** **POST /api/login**
``` ```
...@@ -730,484 +215,9 @@ class RuleBO extends Equatable { ...@@ -730,484 +215,9 @@ class RuleBO extends Equatable {
} }
``` ```
#### 告警模块
**GET /api/home/overview** - 告警首页概览
```
响应 data:
{
"highAlarmCount": 1,
"mediumAlarmCount": 1,
"onlineDeviceCount": 48,
"temperatureAlarm": {
"title": "温度异常告警",
"location": "客房301·A-301智能空开",
"currentTemperature": "85",
"currentVoltage": "220",
"currentCurrent": "3.2",
"waitTime": "2h37m",
"alarmLevel": "紧急"
},
"voltageAlarm": {
"title": "电压波动告警",
"location": "会议室2F-01",
"voltageValue": "248",
"normalVoltage": "235",
"waitTime": "1h19m",
"alarmLevel": "中警"
},
"equipmentList": [
{
"title": "客房305空开",
"subtitle": "38°C·220V·520W",
"status": "正常",
"statusColor": "#1ABC9C"
}
]
}
```
**GET /api/alarms** - 告警列表
```
查询参数:
?status=pending|processed|falseAlarm (可选,默认全部)
响应 data:
[
{
"id": "string",
"title": "string",
"deviceInfo": "string",
"alarmTime": "string",
"processTime": "string",
"status": "pending|processed|falseAlarm",
"level": "高警|中警|低警",
"urgency": "紧急|一般"
}
]
```
**GET /api/alarms/{id}** - 告警详情
```
响应 data:
{
"alarmType": "string",
"deviceInfo": "string",
"alarmLevel": "string",
"urgency": "string",
"currentTemp": "string",
"voltage": "string",
"current": "string",
"triggerTime": "string",
"threshold": "string",
"duration": "string",
"peak": "string",
"linkAction": "string",
"date": "string",
"temperatureSpots": [
{ "x": 0, "y": 40 },
{ "x": 4, "y": 40 }
]
}
```
**GET /api/devices/{id}** - 设备详情
```
响应 data:
{
"deviceName": "string",
"deviceId": "string",
"location": "string",
"status": "string",
"voltage": "string",
"current": "string",
"power": "string",
"temperature": "string",
"powerData": [100, 200, 150],
"tempData": [30, 35, 40]
}
```
#### 巡检模块
**GET /api/inspections** - 巡检任务列表
```
响应 data: 与页面现有 inspection 模块数据一致
```
**GET /api/inspections/{id}/devices** - 巡检设备列表
```
查询参数:
?status=total|on|off|offline|alarm|fault
?rooms=101,102
响应 data:
[
{
"id": "string",
"name": "string",
"type": "string",
"location": "string",
"status": "string",
"time": "string",
"statusColor": "string"
}
]
```
**GET /api/inspections/devices/{id}/detail** - 巡检设备详情
```
响应 data:
{
"deviceId": "string",
"deviceName": "string",
"deviceType": "string",
"deviceStatus": "string",
"deviceModel": "string",
"installLocation": "string",
"area": "string",
"responsiblePerson": "string",
"lastInspectionTime": "string",
"inspectionHistory": [...],
"inspectionItems": [...]
}
```
**GET /api/inspections/devices/{id}/history** - 巡检历史
```
响应 data:
{
"totalCount": 20,
"passCount": 15,
"warningCount": 3,
"failCount": 2,
"records": [
{
"deviceName": "string",
"inspectorName": "string",
"inspectionTime": "string",
"result": "string",
"remark": "string",
"items": [
{ "name": "string", "status": "string", "value": "string" }
]
}
]
}
```
**GET /api/inspections/{id}/topology** - 巡检拓扑
```
响应 data:
{
"deviceName": "string",
"deviceModel": "string",
"deviceCount": 10,
"connectionCount": 11,
"topologyNodes": [
{
"id": "string",
"name": "string",
"status": "string",
"x": 0.0,
"y": 0.0,
"children": [...]
}
]
}
```
#### 管理模块
**GET /api/service/overview** - 管理首页概览
```
响应 data:
{
"pendingCount": 2,
"occupiedRooms": 45,
"vacantRooms": 7,
"floors": ["1楼", "2楼", "3楼", "4楼", "5楼", "6楼"]
}
```
**GET /api/service/rooms** - 房间列表
```
查询参数:
?floor=1楼
?type=occupied|vacant (可选)
?search=302 (可选)
响应 data:
[
{
"roomNumber": "302",
"status": "occupied",
"statusText": "入住中",
"deviceStatus": {
"hasPerson": true,
"powerOn": true,
"wifiNormal": true,
"acOn": true,
"acTemperature": "24",
"lightOn": false,
"tvOn": false,
"curtainOn": false
}
}
]
```
**GET /api/service/rooms/{roomNumber}** - 房间详情
```
响应 data:
{
"roomNumber": "302",
"roomStatus": "入住中",
"statusTags": ["hasPerson", "powerOn", "wifiNormal"],
"roomDevices": [
{ "name": "空调", "iconType": "ac", "isOn": true, "statusText": "制冷 24°C" }
],
"mainPowerOn": true,
"controlDevices": [
{ "name": "空调", "iconType": "ac", "isOn": true, "detailText": "制冷 24°C" },
{ "name": "灯光", "iconType": "light", "isOn": false, "detailText": null }
]
}
```
**POST /api/service/rooms/{roomNumber}/devices/control** - 设备控制
```
请求体:
{
"deviceName": "空调",
"action": "toggle|setTemperature|setSpeed|setMode",
"value": "string|number"
}
响应 data:
{
"success": true
}
```
#### 能耗模块
**GET /api/reports/overview** - 能耗总览
```
响应 data:
{
"reportHeader": {
"title": "string",
"subtitle": "string"
},
"reportMetrics": {
"powerUsage": { "value": 1284, "unit": "kWh", "change": -8, "changeText": "↓ 8%", "progress": 0.6 },
"pendingAlerts": { "value": 3, "unit": "条", "change": null, "changeText": "需关注", "progress": 0.3 }
},
"weeklyPowerUsage": {
"unit": "kWh",
"dateRange": "string",
"data": [
{ "day": "一", "value": 120 }
]
},
"roomStatusDistribution": {
"totalRooms": 52,
"statuses": [
{ "name": "入住中", "count": 45, "color": "#3B82F6" }
]
}
}
```
**GET /api/reports/devices** - 设备能耗列表
```
查询参数:
?type=all|smartBreaker|guestControl|network
响应 data:
[
{
"id": "string",
"name": "string",
"room": "string",
"type": "smartBreaker|guestControl|network",
"online": true,
"status": "string",
"lastUpdate": "string"
}
]
```
**GET /api/reports/devices/{id}** - 设备能耗详情
```
响应 data: 与设备能耗详情页字段一致
```
**GET /api/reports/energy** - 区域能耗
```
响应 data:
{
"todayEnergy": 1284,
"todayEnergyChange": -8,
"monthEnergy": 38420,
"monthEnergyChange": -5,
"monthBill": 6982,
"hourlyData": [45, 38, 32, ...],
"zoneData": [
{ "name": "客房区域", "percentage": 68, "energy": 873 }
]
}
```
**GET /api/reports/rooms** - 房间能耗报告
```
查询参数:
?floor=1
响应 data:
{
"floors": ["1楼", "2楼", "3楼"],
"selectedFloor": "1楼",
"rooms": [
{
"roomNumber": "101",
"status": "occupied",
"statusText": "入住中",
"deviceStatus": { ... }
}
]
}
```
**GET /api/reports/rules** - 规则列表
```
响应 data:
[
{
"id": "string",
"name": "string",
"description": "string",
"enabled": true,
"triggerCondition": "string",
"action": "string",
"iconType": "string"
}
]
```
**POST /api/reports/rules/{id}/toggle** - 规则开关
```
请求体:
{
"enabled": true
}
响应 data:
{
"success": true
}
```
--- ---
## 4. 需要创建的文件清单
### 4.1 BO 模型文件(7 个)
| 文件 | 路径 |
|------|------|
| `alarm_bo.dart` | `lib/models/bo/alarm_bo.dart` |
| `device_bo.dart` | `lib/models/bo/device_bo.dart` |
| `inspection_bo.dart` | `lib/models/bo/inspection_bo.dart` |
| `topology_bo.dart` | `lib/models/bo/topology_bo.dart` |
| `energy_bo.dart` | `lib/models/bo/energy_bo.dart` |
| `room_bo.dart` | `lib/models/bo/room_bo.dart` |
| `rule_bo.dart` | `lib/models/bo/rule_bo.dart` |
### 4.2 Repository 文件(按模块,约 10 个)
| 文件 | 对应接口 |
|------|---------|
| `alarm_repository.dart` | #4, #5, #6 |
| `device_repository.dart` | #7 |
| `inspection_repository.dart` | #8, #9, #10, #11, #12 |
| `service_repository.dart` | #13, #14, #15, #16 |
| `report_repository.dart` | #17, #18, #19, #20, #21, #22, #23 |
| `user_repository.dart` | #2, #3 |
### 4.3 Service 文件(按模块,约 10 个)
与 Repository 一一对应,封装业务逻辑。
### 4.4 需要修改的 Cubit 文件(15 个)
| Cubit 文件 | 改造内容 |
|-----------|---------|
| `home_index_cubit.dart` | 构造函数注入 `HomeService``initData()` 改为调用 API |
| `abnormal_list_cubit.dart` | 注入 `AlarmService`,加载告警列表 |
| `abnormal_cubit.dart` | 注入 `AlarmService`,通过路由参数加载告警详情 |
| `device_cubit.dart` | 注入 `DeviceService`,加载设备详情 |
| `inspection_cubit.dart` | 注入 `InspectionService`,加载巡检任务 |
| `inspection_device_cubit.dart` | 注入 `InspectionService`,加载设备巡检详情 |
| `inspection_history_cubit.dart` | 注入 `InspectionService`,加载巡检历史 |
| `inspection_topology_cubit.dart` | 注入 `InspectionService`,加载拓扑数据 |
| `service_index_cubit.dart` | 注入 `ServiceRoomService`,加载管理首页 |
| `service_room_cubit.dart` | 注入 `ServiceRoomService`,加载房间详情 |
| `service_device_cubit.dart` | 注入 `ServiceRoomService`,设备控制 |
| `report_index_cubit.dart` | 注入 `ReportService`,加载能耗总览 |
| `device_list_cubit.dart` | 注入 `ReportService`,加载设备能耗列表 |
| `energy_cubit.dart` | 注入 `ReportService`,加载区域能耗 |
| `room_report_cubit.dart` | 注入 `ReportService`,加载房间能耗 |
| `rule_management_cubit.dart` | 注入 `ReportService`,加载/切换规则 |
| `profile_cubit.dart` | 注入 `UserService`,加载用户信息 |
---
## 5. AI 自动对接指南
### 5.1 AI 可以自动完成的操作
1. **创建 BO 模型文件**:根据本文档第 2 节的 BO 定义,直接复制代码到对应文件
2. **创建 Repository 文件**:根据本文档第 3 节的接口定义,按模板生成
3. **创建 Service 文件**:根据 Repository 方法,按模板生成
4. **修改 Cubit 文件**:将 `initData()` mock 替换为 Service 调用,添加 `isLoading/error` 状态管理
5. **修改 View 文件**:在 `BlocProvider` 中注入 Service 依赖(从 `create: (_) => XxxCubit()` 改为 `create: (_) => XxxCubit(service: XxxService(...))`
### 5.2 需要人工确认/介入的操作
| 事项 | 原因 | 介入方式 |
|------|------|---------|
| **API 地址确认** | `constants.dart` 中的 `baseUrl` 需要替换为真实后端地址 | 人工修改配置文件 |
| **接口路径确认** | 本文档定义的接口路径(如 `/api/alarms`)是约定,实际后端路径可能不同 | 对照后端 Swagger/YApi 文档核对 |
| **字段名映射** | JSON 字段名可能与本文档定义不一致(如后端用 `device_info` 而非 `deviceInfo`) | 对照后端文档调整 `fromJson` |
| **数据类型差异** | 数值类型可能需要调整(int/double/String) | 对照后端文档调整 BO 字段类型 |
| **鉴权调试** | Token 传递、401 处理逻辑是否正确 | 登录后测试接口调用 |
| **分页逻辑** | 当前页面未设计分页,如果后端数据量大需要补充分页 | 评估是否需要加载更多/下拉刷新 |
| **错误文案** | 后端返回的错误信息可能需要前端映射 | 检查 `msg` 字段是否适合直接展示 |
### 5.3 对接执行顺序(建议)
```
第一阶段:基础设施
1. 创建所有 BO 模型文件
2. 创建所有 Repository 文件
3. 创建所有 Service 文件
第二阶段:逐模块改造
4. 改造认证模块(已在 main.dart 中注入,无需修改)
5. 改造告警模块(4 个 Cubit)
6. 改造巡检模块(4 个 Cubit)
7. 改造管理模块(3 个 Cubit)
8. 改造能耗模块(5 个 Cubit)
9. 改造个人中心(1 个 Cubit)
第三阶段:联调验证
10. 修改 main.dart 注入全局 Service(如需要)
11. 逐页面运行验证
```
---
## 6. 注意事项 ## 6. 注意事项
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment