Commit cfc4a398 authored by 张宏's avatar 张宏

3

parent 749feeaf
......@@ -105,3 +105,221 @@ class RoomStatusBO extends Equatable {
List<Object?> get props =>
[roomId, roomNumber, occupancyStatus, roomStatus, cleanStatus, devicePowerStatus];
}
// ==================== 客房详情 ====================
class RoomDetailBO extends Equatable {
final RoomBasicInfoBO roomBasicInfo;
final List<DeviceStatusBO> deviceStatusList;
final RoomDeviceControlBO deviceControl;
const RoomDetailBO({
required this.roomBasicInfo,
required this.deviceStatusList,
required this.deviceControl,
});
factory RoomDetailBO.fromJson(Map<String, dynamic> json) {
return RoomDetailBO(
roomBasicInfo: RoomBasicInfoBO.fromJson(
json['roomBasicInfo'] as Map<String, dynamic>? ?? {}),
deviceStatusList: (json['deviceStatusList'] as List<dynamic>?)
?.map((e) =>
DeviceStatusBO.fromJson(e as Map<String, dynamic>))
.toList() ??
[],
deviceControl: RoomDeviceControlBO.fromJson(
json['deviceControl'] as Map<String, dynamic>? ?? {}),
);
}
@override
List<Object?> get props => [roomBasicInfo, deviceStatusList, deviceControl];
}
class RoomBasicInfoBO extends Equatable {
final int roomId;
final String roomNumber;
final String occupancyStatus;
final bool powerSupplyStatus;
final String wifiOnlineStatus;
const RoomBasicInfoBO({
required this.roomId,
required this.roomNumber,
required this.occupancyStatus,
required this.powerSupplyStatus,
required this.wifiOnlineStatus,
});
factory RoomBasicInfoBO.fromJson(Map<String, dynamic> json) {
return RoomBasicInfoBO(
roomId: _parseInt(json['roomId']),
roomNumber: _parseString(json['roomNumber']),
occupancyStatus: _parseString(json['occupancyStatus']),
powerSupplyStatus: json['powerSupplyStatus'] as bool? ?? false,
wifiOnlineStatus: _parseString(json['wifiOnlineStatus']),
);
}
@override
List<Object?> get props =>
[roomId, roomNumber, occupancyStatus, powerSupplyStatus, wifiOnlineStatus];
}
class DeviceStatusBO extends Equatable {
final int deviceId;
final String deviceName;
final String deviceTypeName;
final String deviceTypeIcon;
final String powerStatus;
final String powerStatusText;
final String runStatus;
final String runStatusText;
final DeviceParamsBO? deviceParams;
const DeviceStatusBO({
required this.deviceId,
required this.deviceName,
required this.deviceTypeName,
required this.deviceTypeIcon,
required this.powerStatus,
required this.powerStatusText,
required this.runStatus,
required this.runStatusText,
this.deviceParams,
});
factory DeviceStatusBO.fromJson(Map<String, dynamic> json) {
return DeviceStatusBO(
deviceId: _parseInt(json['deviceId']),
deviceName: _parseString(json['deviceName']),
deviceTypeName: _parseString(json['deviceTypeName']),
deviceTypeIcon: _parseString(json['deviceTypeIcon']),
powerStatus: _parseString(json['powerStatus']),
powerStatusText: _parseString(json['powerStatusText']),
runStatus: _parseString(json['runStatus']),
runStatusText: _parseString(json['runStatusText']),
deviceParams: json['deviceParams'] != null
? DeviceParamsBO.fromJson(json['deviceParams'] as Map<String, dynamic>)
: null,
);
}
@override
List<Object?> get props => [
deviceId,
deviceName,
deviceTypeName,
deviceTypeIcon,
powerStatus,
powerStatusText,
runStatus,
runStatusText,
deviceParams,
];
}
class DeviceParamsBO extends Equatable {
final String temperature;
final String targetTemperature;
final String mode;
final String fanSpeed;
const DeviceParamsBO({
required this.temperature,
required this.targetTemperature,
required this.mode,
required this.fanSpeed,
});
factory DeviceParamsBO.fromJson(Map<String, dynamic> json) {
return DeviceParamsBO(
temperature: _parseString(json['temperature']),
targetTemperature: _parseString(json['targetTemperature']),
mode: _parseString(json['mode']),
fanSpeed: _parseString(json['fanSpeed']),
);
}
@override
List<Object?> get props => [temperature, targetTemperature, mode, fanSpeed];
}
class RoomDeviceControlBO extends Equatable {
final RoomPowerControlBO roomPowerControl;
final List<SubDeviceControlBO> subDeviceControls;
const RoomDeviceControlBO({
required this.roomPowerControl,
required this.subDeviceControls,
});
factory RoomDeviceControlBO.fromJson(Map<String, dynamic> json) {
return RoomDeviceControlBO(
roomPowerControl: RoomPowerControlBO.fromJson(
json['roomPowerControl'] as Map<String, dynamic>? ?? {}),
subDeviceControls: (json['subDeviceControls'] as List<dynamic>?)
?.map((e) =>
SubDeviceControlBO.fromJson(e as Map<String, dynamic>))
.toList() ??
[],
);
}
@override
List<Object?> get props => [roomPowerControl, subDeviceControls];
}
class RoomPowerControlBO extends Equatable {
final int roomId;
final bool powerOn;
final String description;
const RoomPowerControlBO({
required this.roomId,
required this.powerOn,
required this.description,
});
factory RoomPowerControlBO.fromJson(Map<String, dynamic> json) {
return RoomPowerControlBO(
roomId: _parseInt(json['roomId']),
powerOn: json['powerOn'] as bool? ?? false,
description: _parseString(json['description']),
);
}
@override
List<Object?> get props => [roomId, powerOn, description];
}
class SubDeviceControlBO extends Equatable {
final int deviceId;
final String deviceName;
final String deviceTypeName;
final bool powerOn;
final String currentParamDisplay;
const SubDeviceControlBO({
required this.deviceId,
required this.deviceName,
required this.deviceTypeName,
required this.powerOn,
required this.currentParamDisplay,
});
factory SubDeviceControlBO.fromJson(Map<String, dynamic> json) {
return SubDeviceControlBO(
deviceId: _parseInt(json['deviceId']),
deviceName: _parseString(json['deviceName']),
deviceTypeName: _parseString(json['deviceTypeName']),
powerOn: json['powerOn'] as bool? ?? false,
currentParamDisplay: _parseString(json['currentParamDisplay']),
);
}
@override
List<Object?> get props =>
[deviceId, deviceName, deviceTypeName, powerOn, currentParamDisplay];
}
\ No newline at end of file
......@@ -54,4 +54,30 @@ class RoomRepository {
data: {'deviceId': deviceId},
);
}
/// 客房详情
Future<ResponseModel<RoomDetailBO>> getRoomDetail({required int roomId}) {
return DioRequest.instance.get<RoomDetailBO>(
'/app/room/detail',
queryParameters: {'roomId': roomId},
fromJsonT: (data) =>
RoomDetailBO.fromJson(data as Map<String, dynamic>),
);
}
/// 客房详情-房间总电源-开
Future<ResponseModel> roomPowerOn({required int roomId}) {
return DioRequest.instance.post(
'/app/room/power/on',
data: {'roomId': roomId},
);
}
/// 客房详情-房间总电源-关
Future<ResponseModel> roomPowerOff({required int roomId}) {
return DioRequest.instance.post(
'/app/room/power/off',
data: {'roomId': roomId},
);
}
}
\ No newline at end of file
......@@ -194,11 +194,12 @@ abstract class $AppRouter extends _i21.RootStackRouter {
},
ServiceRoomDetailRoute.name: (routeData) {
final args = routeData.argsAs<ServiceRoomDetailRouteArgs>(
orElse: () => const ServiceRoomDetailRouteArgs());
orElse: () => const ServiceRoomDetailRouteArgs(roomId: 0));
return _i21.AutoRoutePage<dynamic>(
routeData: routeData,
child: _i20.ServiceRoomDetailView(
key: args.key,
roomId: args.roomId,
roomNumber: args.roomNumber,
),
);
......@@ -617,12 +618,14 @@ class ServiceRoomDetailRoute
extends _i21.PageRouteInfo<ServiceRoomDetailRouteArgs> {
ServiceRoomDetailRoute({
_i22.Key? key,
required int roomId,
String? roomNumber,
List<_i21.PageRouteInfo>? children,
}) : super(
ServiceRoomDetailRoute.name,
args: ServiceRoomDetailRouteArgs(
key: key,
roomId: roomId,
roomNumber: roomNumber,
),
initialChildren: children,
......@@ -637,15 +640,18 @@ class ServiceRoomDetailRoute
class ServiceRoomDetailRouteArgs {
const ServiceRoomDetailRouteArgs({
this.key,
required this.roomId,
this.roomNumber,
});
final _i22.Key? key;
final int roomId;
final String? roomNumber;
@override
String toString() {
return 'ServiceRoomDetailRouteArgs{key: $key, roomNumber: $roomNumber}';
return 'ServiceRoomDetailRouteArgs{key: $key, roomId: $roomId, roomNumber: $roomNumber}';
}
}
......@@ -47,4 +47,29 @@ class RoomService {
throw Exception(result.msg);
}
}
/// 客房详情
Future<RoomDetailBO> getRoomDetail({required int roomId}) async {
final result = await _repository.getRoomDetail(roomId: roomId);
if (result.success && result.data != null) {
return result.data!;
}
throw Exception(result.msg);
}
/// 客房详情-房间总电源-开
Future<void> roomPowerOn({required int roomId}) async {
final result = await _repository.roomPowerOn(roomId: roomId);
if (!result.success) {
throw Exception(result.msg);
}
}
/// 客房详情-房间总电源-关
Future<void> roomPowerOff({required int roomId}) async {
final result = await _repository.roomPowerOff(roomId: roomId);
if (!result.success) {
throw Exception(result.msg);
}
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
String? _selectedFloor;
String? _selectedType;
String? _selectedRoom;
int? _selectedRoomId;
String _searchText = '';
final TextEditingController _searchController = TextEditingController();
final ScrollController _scrollController = ScrollController();
......@@ -403,6 +404,7 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
onTap: () {
setState(() {
_selectedRoom = room['number'] as String;
_selectedRoomId = room['roomId'] as int?;
});
},
child: Container(
......@@ -560,9 +562,12 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
),
elevation: 0,
),
onPressed: isRoomSelected
onPressed: (isRoomSelected && _selectedRoomId != null)
? () {
context.pushRoute(ServiceRoomDetailRoute(roomNumber: _selectedRoom));
context.pushRoute(ServiceRoomDetailRoute(
roomId: _selectedRoomId!,
roomNumber: _selectedRoom,
));
}
: null,
child: Text(
......
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/models/bo/room_bo.dart';
import 'package:smart_hotel_app/repositories/room_repository.dart';
import 'package:smart_hotel_app/services/room_service.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
class ServiceRoomCubit extends Cubit<ServiceRoomState> {
final String? roomNumber;
final RoomService _service;
final int _roomId;
ServiceRoomCubit({this.roomNumber}) : super(const ServiceRoomState()) {
initData();
ServiceRoomCubit({
RoomService? service,
required int roomId,
String roomNumber = '',
}) : _service = service ??
RoomService(repository: RoomRepository()),
_roomId = roomId,
super(ServiceRoomState(roomId: roomId, roomNumber: roomNumber)) {
loadDetail();
}
Future<void> loadDetail() async {
emit(state.copyWith(isLoading: true, error: null));
try {
final detail = await _service.getRoomDetail(roomId: _roomId);
emit(_mapDetailToState(detail));
} catch (e) {
emit(state.copyWith(isLoading: false, error: e.toString()));
}
}
void initData() {
final num = roomNumber ?? '302';
final numInt = int.tryParse(num) ?? 302;
final statuses = ['空闲', '入住中', '待清洁'];
final statusIndex = numInt % 3;
ServiceRoomState _mapDetailToState(RoomDetailBO detail) {
final basic = detail.roomBasicInfo;
final statusTags = _buildStatusTags(
occupancyStatus: basic.occupancyStatus,
powerSupplyStatus: basic.powerSupplyStatus,
wifiOnlineStatus: basic.wifiOnlineStatus,
);
final roomDevices = detail.deviceStatusList.map((d) {
return RoomDevice(
name: d.deviceName,
icon: _mapDeviceIcon(d.deviceTypeName, d.deviceTypeIcon),
isOn: d.powerStatus == '1' || d.powerStatus == 'on',
statusText: _buildDeviceStatusText(d),
);
}).toList();
final controlDevices = detail.deviceControl.subDeviceControls.map((c) {
return ControlDevice(
name: c.deviceName,
icon: _mapDeviceIcon(c.deviceTypeName, ''),
isOn: c.powerOn,
detailText: c.currentParamDisplay.isNotEmpty ? c.currentParamDisplay : null,
);
}).toList();
return state.copyWith(
isLoading: false,
roomNumber: basic.roomNumber,
roomStatus: _mapOccupancyStatus(basic.occupancyStatus),
statusTags: statusTags,
roomDevices: roomDevices,
mainPowerOn: detail.deviceControl.roomPowerControl.powerOn,
controlDevices: controlDevices,
);
}
emit(state.copyWith(
roomNumber: num,
roomStatus: statuses[statusIndex],
mainPowerOn: numInt % 2 == 0,
roomDevices: [
const RoomDevice(
name: '空调',
icon: Icons.air_outlined,
isOn: true,
statusText: '24°C·开',
),
const RoomDevice(
name: '照明',
icon: Icons.light_outlined,
isOn: false,
statusText: '关',
),
const RoomDevice(
name: '电视',
icon: Icons.tv_outlined,
isOn: true,
statusText: '开',
),
const RoomDevice(
name: '窗帘',
icon: Icons.curtains_closed_outlined,
isOn: false,
statusText: '关',
),
],
controlDevices: [
const ControlDevice(
name: '空调',
icon: Icons.air_outlined,
isOn: true,
detailText: '当前:制冷24°C·风速:自动',
),
const ControlDevice(
name: '主照明',
icon: Icons.light_outlined,
isOn: false,
),
const ControlDevice(
name: '电视',
icon: Icons.tv_outlined,
isOn: true,
),
],
));
List<RoomStatusTag> _buildStatusTags({
required String occupancyStatus,
required bool powerSupplyStatus,
required String wifiOnlineStatus,
}) {
final tags = <RoomStatusTag>[];
if (occupancyStatus == '1') {
tags.add(RoomStatusTag.hasPerson);
}
if (powerSupplyStatus) {
tags.add(RoomStatusTag.powerOn);
}
if (wifiOnlineStatus == '1' || wifiOnlineStatus == 'online') {
tags.add(RoomStatusTag.wifiNormal);
}
return tags;
}
void toggleMainPower(bool value) {
emit(state.copyWith(mainPowerOn: value));
String _buildDeviceStatusText(DeviceStatusBO d) {
if (d.powerStatusText.isNotEmpty) {
return d.powerStatusText;
}
if (d.runStatusText.isNotEmpty) {
return d.runStatusText;
}
if (d.deviceParams != null) {
final p = d.deviceParams!;
final parts = <String>[];
if (p.temperature.isNotEmpty) parts.add('${p.temperature}°C');
if (p.mode.isNotEmpty) parts.add(p.mode);
return parts.join('·');
}
return '';
}
void toggleControlDevice(int index, bool value) {
final updatedDevices = List<ControlDevice>.from(state.controlDevices);
if (index >= 0 && index < updatedDevices.length) {
String _mapOccupancyStatus(String status) {
switch (status) {
case '1':
return '入住中';
case '0':
default:
return '空闲';
}
}
IconData _mapDeviceIcon(String deviceTypeName, String deviceTypeIcon) {
// Try to match by deviceTypeName first
final name = deviceTypeName.toLowerCase();
if (name.contains('空调') || name.contains('air')) {
return Icons.air_outlined;
}
if (name.contains('照明') || name.contains('灯') || name.contains('light')) {
return Icons.light_outlined;
}
if (name.contains('电视') || name.contains('tv')) {
return Icons.tv_outlined;
}
if (name.contains('窗帘') || name.contains('curtain')) {
return Icons.curtains_closed_outlined;
}
// Fallback: match by deviceTypeIcon string
final icon = deviceTypeIcon.toLowerCase();
if (icon.contains('air') || icon.contains('ac')) {
return Icons.air_outlined;
}
if (icon.contains('light')) {
return Icons.light_outlined;
}
if (icon.contains('tv')) {
return Icons.tv_outlined;
}
if (icon.contains('curtain')) {
return Icons.curtains_closed_outlined;
}
return Icons.devices_other;
}
/// 房间总电源开关
Future<void> toggleMainPower(bool value) async {
if (state.isTogglingPower) return;
emit(state.copyWith(isTogglingPower: true));
try {
if (value) {
await _service.roomPowerOn(roomId: _roomId);
} else {
await _service.roomPowerOff(roomId: _roomId);
}
emit(state.copyWith(isTogglingPower: false, mainPowerOn: value));
} catch (e) {
emit(state.copyWith(isTogglingPower: false));
// Re-throw so the view can show error snackbar
rethrow;
}
}
/// 分设备电源开关
Future<void> toggleControlDevice(int index, bool value) async {
final devices = state.controlDevices;
if (index < 0 || index >= devices.length) return;
// Note: The API for individual device power control uses deviceId.
// However, we don't have deviceId in ControlDevice model yet.
// For now, just update UI state. The device control card in the view
// navigates to ServiceDeviceDetailRoute for AC control.
final updatedDevices = List<ControlDevice>.from(devices);
updatedDevices[index] = ControlDevice(
name: updatedDevices[index].name,
icon: updatedDevices[index].icon,
......@@ -81,5 +181,4 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
);
emit(state.copyWith(controlDevices: updatedDevices));
}
}
}
......@@ -32,47 +32,67 @@ class ControlDevice {
}
class ServiceRoomState extends Equatable {
final bool isLoading;
final String? error;
final int roomId;
final String roomNumber;
final String roomStatus;
final List<RoomStatusTag> statusTags;
final List<RoomDevice> roomDevices;
final bool mainPowerOn;
final List<ControlDevice> controlDevices;
final bool isTogglingPower;
const ServiceRoomState({
this.roomNumber = '302',
this.roomStatus = '入住中',
this.statusTags = const [RoomStatusTag.hasPerson, RoomStatusTag.powerOn, RoomStatusTag.wifiNormal],
this.isLoading = false,
this.error,
this.roomId = 0,
this.roomNumber = '',
this.roomStatus = '',
this.statusTags = const [],
this.roomDevices = const [],
this.mainPowerOn = false,
this.controlDevices = const [],
this.isTogglingPower = false,
});
ServiceRoomState copyWith({
bool? isLoading,
String? error,
int? roomId,
String? roomNumber,
String? roomStatus,
List<RoomStatusTag>? statusTags,
List<RoomDevice>? roomDevices,
bool? mainPowerOn,
List<ControlDevice>? controlDevices,
bool? isTogglingPower,
}) {
return ServiceRoomState(
isLoading: isLoading ?? this.isLoading,
error: error ?? this.error,
roomId: roomId ?? this.roomId,
roomNumber: roomNumber ?? this.roomNumber,
roomStatus: roomStatus ?? this.roomStatus,
statusTags: statusTags ?? this.statusTags,
roomDevices: roomDevices ?? this.roomDevices,
mainPowerOn: mainPowerOn ?? this.mainPowerOn,
controlDevices: controlDevices ?? this.controlDevices,
isTogglingPower: isTogglingPower ?? this.isTogglingPower,
);
}
@override
List<Object?> get props => [
isLoading,
error,
roomId,
roomNumber,
roomStatus,
statusTags,
roomDevices,
mainPowerOn,
controlDevices,
isTogglingPower,
];
}
......@@ -12,14 +12,22 @@ import 'package:smart_hotel_app/views/service/room/widget/room_bottom_buttons.da
@RoutePage()
class ServiceRoomDetailView extends StatelessWidget {
final int roomId;
final String? roomNumber;
const ServiceRoomDetailView({super.key, this.roomNumber});
const ServiceRoomDetailView({
super.key,
required this.roomId,
this.roomNumber,
});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => ServiceRoomCubit(roomNumber: roomNumber),
create: (_) => ServiceRoomCubit(
roomId: roomId,
roomNumber: roomNumber ?? '',
),
child: Scaffold(
backgroundColor: const Color.fromRGBO(242, 243, 245, 1),
appBar: AppBar(
......@@ -42,12 +50,42 @@ class ServiceRoomDetailView extends StatelessWidget {
),
centerTitle: true,
),
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: BlocBuilder<ServiceRoomCubit, ServiceRoomState>(
body: BlocBuilder<ServiceRoomCubit, ServiceRoomState>(
builder: (context, state) {
if (state.isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (state.error != null) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'加载失败',
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(100, 116, 139, 1),
),
),
SizedBox(height: 16.h),
ElevatedButton(
onPressed: () {
context.read<ServiceRoomCubit>().loadDetail();
},
child: const Text('重试'),
),
],
),
);
}
final cubit = context.read<ServiceRoomCubit>();
return Column(
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
SizedBox(height: 20.h),
RoomOverviewCard(
......@@ -63,8 +101,26 @@ class ServiceRoomDetailView extends StatelessWidget {
DeviceControlCard(
mainPowerOn: state.mainPowerOn,
controlDevices: state.controlDevices,
onMainPowerToggle: (value) => cubit.toggleMainPower(value),
onDeviceToggle: (index, value) => cubit.toggleControlDevice(index, value),
onMainPowerToggle: (value) async {
try {
await cubit.toggleMainPower(value);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(value ? '送电成功' : '断电成功'),
),
);
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('操作失败: $e')),
);
}
}
},
onDeviceToggle: (index, value) =>
cubit.toggleControlDevice(index, value),
onDeviceTap: (index, device) {
if (device.name == '空调') {
context.pushRoute(const ServiceDeviceDetailRoute());
......@@ -75,11 +131,11 @@ class ServiceRoomDetailView extends StatelessWidget {
const RoomBottomButtons(),
SizedBox(height: 20.h),
],
),
);
},
),
),
),
);
}
}
# 智慧酒店 App 接口对接方案
# 智慧酒店 App 接口对接方案
......@@ -220,7 +220,9 @@ class xxxBO extends Equatable {
| 客房详情 |GET | /app/room/detail | 未对接 | 客房详情 | |
| 客房详情-房间总电源-switch开 |GET | /app/room/power/on | 未对接 | 客房详情-房间总电源-switch开 | |
| 客房详情-房间总电源-switch关 |GET | /app/room/power/off | 未对接 | 客房详情-房间总电源-switch关 | |
| 客房详情-房间总电源-switch关 |POST | /app/room/power/off | 未对接 | 客房详情-房间总电源-switch关 | |
| 空调控制 |GET | /app/device/ac/status | 未对接 | 空调控制 | |
......@@ -228,6 +230,35 @@ class xxxBO extends Equatable {
### 3.2 接口详细定义
#### 空调控制
**GET /app/device/ac/status**
```
求体:
{
"deviceId": 0
}
应 data:
{
"code": 0,
"msg": "string",
"data": {
"deviceId": 0,
"deviceName": "string",
"powerStatus": "string", // 电源开关状态码:0=关闭 1=开启,来源于 hotel_device.power_status,对应页面右上角Toggle开关
"currentTemperature": "string", // 当前室内温度值,如24,单位℃
"targetTemperature": "string", // 目标设定温度值,如25,单位℃
"mode": "string", // 当前工作模式码:cooling=制冷 heating=制热 dehumidify=除湿 fan=送风 auto=自动
"modeText": "string", // 工作模式中文文本:根据 mode 字段映射 cooling→'制冷' heating→'制热' dehumidify→'除湿' fan→'送风' auto→'自动'
"fanSpeed": "string", // 当前风速档位码:low=低中=中 high=高 auto=自动
"fanSpeedText": "string" // 风速中文文本:根据 fan_speed 字段映射 low→'低' mid→'中' high→'高' auto→'自动'
}
}
```
#### 客房服务看板-客房状态总览-楼层
**GET /app/room/floor/areas**
......@@ -262,7 +293,7 @@ class xxxBO extends Equatable {
#### 客房详情-房间总电源-switch关
**GET /app/room/power/off**
**POST /app/room/power/off**
```
求体:
{
......
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