Commit 3a517340 authored by 张宏's avatar 张宏

.

parent 4f547179
......@@ -13,45 +13,55 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
final num = roomNumber ?? '302';
final numInt = int.tryParse(num) ?? 302;
final statuses = ['空闲', '入住中', '待清洁'];
final roomTypes = ['标准大床房', '豪华双床房', '商务套房', '总统套房'];
final guestNames = ['张先生', '李女士', '王先生', '赵女士', '刘先生'];
final months = ['5月', '6月', '7月', '8月'];
final statusIndex = numInt % 3;
final typeIndex = numInt % 4;
final guestIndex = numInt % 5;
final monthIndex = (numInt ~/ 100) % 4;
final hasGuest = numInt % 2 == 0;
final now = DateTime.now();
final refreshTime = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}';
emit(state.copyWith(
roomDetail: {
'roomNumber': num,
'status': statuses[statusIndex],
'guestName': statusIndex == 0 ? null : guestNames[guestIndex],
'checkInDate': statusIndex == 0 ? null : '${months[monthIndex]}${(numInt % 20) + 1}日',
'checkOutDate': statusIndex == 0 ? null : '${months[monthIndex]}${(numInt % 20) + 3}日',
'roomType': roomTypes[typeIndex],
},
roomStatus: {
'hasGuest': hasGuest,
'guestRefreshTime': refreshTime,
'powerOn': true,
'currentPower': '1.24kW',
'wifiNormal': true,
'wifiSignal': '-45dBm',
},
roomNumber: num,
roomStatus: statuses[statusIndex],
mainPowerOn: numInt % 2 == 0,
devices: [
{'name': '空调', 'icon': Icons.air_outlined, 'status': '24°C·开', 'isOn': true},
{'name': '照明', 'icon': Icons.light_outlined, 'status': '关', 'isOn': false},
{'name': '电视', 'icon': Icons.tv_outlined, 'status': '开', 'isOn': true},
{'name': '窗帘', 'icon': Icons.curtains_closed_outlined, 'status': '关', 'isOn': false},
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: '关',
),
],
deviceControls: [
{'name': '空调', 'icon': Icons.air_outlined, 'status': '当前:制冷24°C·风速:自动', 'isOn': true},
{'name': '主照明', 'icon': Icons.light_outlined, 'status': null, 'isOn': false},
{'name': '电视', 'icon': Icons.tv_outlined, 'status': null, 'isOn': true},
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,
),
],
));
}
......@@ -59,4 +69,17 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
void toggleMainPower(bool value) {
emit(state.copyWith(mainPowerOn: value));
}
void toggleControlDevice(int index, bool value) {
final updatedDevices = List<ControlDevice>.from(state.controlDevices);
if (index >= 0 && index < updatedDevices.length) {
updatedDevices[index] = ControlDevice(
name: updatedDevices[index].name,
icon: updatedDevices[index].icon,
isOn: value,
detailText: updatedDevices[index].detailText,
);
emit(state.copyWith(controlDevices: updatedDevices));
}
}
}
\ No newline at end of file
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
enum RoomStatusTag { hasPerson, powerOn, wifiNormal }
class RoomDevice {
final String name;
final IconData icon;
final bool isOn;
final String? statusText;
const RoomDevice({
required this.name,
required this.icon,
this.isOn = false,
this.statusText,
});
}
class ControlDevice {
final String name;
final IconData icon;
final bool isOn;
final String? detailText;
const ControlDevice({
required this.name,
required this.icon,
this.isOn = false,
this.detailText,
});
}
class ServiceRoomState extends Equatable {
final Map<String, dynamic> roomDetail;
final Map<String, dynamic> roomStatus;
final String roomNumber;
final String roomStatus;
final List<RoomStatusTag> statusTags;
final List<RoomDevice> roomDevices;
final bool mainPowerOn;
final List<Map<String, dynamic>> devices;
final List<Map<String, dynamic>> deviceControls;
final List<ControlDevice> controlDevices;
const ServiceRoomState({
this.roomDetail = const {},
this.roomStatus = const {},
this.roomNumber = '302',
this.roomStatus = '入住中',
this.statusTags = const [RoomStatusTag.hasPerson, RoomStatusTag.powerOn, RoomStatusTag.wifiNormal],
this.roomDevices = const [],
this.mainPowerOn = false,
this.devices = const [],
this.deviceControls = const [],
this.controlDevices = const [],
});
ServiceRoomState copyWith({
Map<String, dynamic>? roomDetail,
Map<String, dynamic>? roomStatus,
String? roomNumber,
String? roomStatus,
List<RoomStatusTag>? statusTags,
List<RoomDevice>? roomDevices,
bool? mainPowerOn,
List<Map<String, dynamic>>? devices,
List<Map<String, dynamic>>? deviceControls,
List<ControlDevice>? controlDevices,
}) {
return ServiceRoomState(
roomDetail: roomDetail ?? this.roomDetail,
roomNumber: roomNumber ?? this.roomNumber,
roomStatus: roomStatus ?? this.roomStatus,
statusTags: statusTags ?? this.statusTags,
roomDevices: roomDevices ?? this.roomDevices,
mainPowerOn: mainPowerOn ?? this.mainPowerOn,
devices: devices ?? this.devices,
deviceControls: deviceControls ?? this.deviceControls,
controlDevices: controlDevices ?? this.controlDevices,
);
}
@override
List<Object?> get props => [
roomDetail,
roomNumber,
roomStatus,
statusTags,
roomDevices,
mainPowerOn,
devices,
deviceControls,
controlDevices,
];
}
\ No newline at end of file
......@@ -4,9 +4,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_cubit.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
import 'package:smart_hotel_app/views/service/room/widget/bottom_operation_block.dart';
import 'package:smart_hotel_app/views/service/room/widget/device_control_block.dart';
import 'package:smart_hotel_app/views/service/room/widget/room_info_block.dart';
import 'package:smart_hotel_app/views/service/room/widget/room_overview_card.dart';
import 'package:smart_hotel_app/views/service/room/widget/room_device_status_card.dart';
import 'package:smart_hotel_app/views/service/room/widget/device_control_card.dart';
import 'package:smart_hotel_app/views/service/room/widget/room_bottom_buttons.dart';
@RoutePage()
class ServiceRoomDetailView extends StatelessWidget {
......@@ -44,21 +45,28 @@ class ServiceRoomDetailView extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: BlocBuilder<ServiceRoomCubit, ServiceRoomState>(
builder: (context, state) {
final cubit = context.read<ServiceRoomCubit>();
return Column(
children: [
SizedBox(height: 20.h),
RoomInfoBlock(
roomDetail: state.roomDetail,
RoomOverviewCard(
roomNumber: state.roomNumber,
roomStatus: state.roomStatus,
statusTags: state.statusTags,
),
SizedBox(height: 20.h),
DeviceControlBlock(
RoomDeviceStatusCard(
devices: state.roomDevices,
),
SizedBox(height: 20.h),
DeviceControlCard(
mainPowerOn: state.mainPowerOn,
deviceControls: state.deviceControls,
devices: state.devices,
controlDevices: state.controlDevices,
onMainPowerToggle: (value) => cubit.toggleMainPower(value),
onDeviceToggle: (index, value) => cubit.toggleControlDevice(index, value),
),
SizedBox(height: 20.h),
const BottomOperationBlock(),
const RoomBottomButtons(),
SizedBox(height: 20.h),
],
);
......
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_switch/flutter_switch.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
class DeviceControlCard extends StatelessWidget {
final bool mainPowerOn;
final List<ControlDevice> controlDevices;
final Function(bool) onMainPowerToggle;
final Function(int, bool) onDeviceToggle;
const DeviceControlCard({
super.key,
required this.mainPowerOn,
required this.controlDevices,
required this.onMainPowerToggle,
required this.onDeviceToggle,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24.r),
),
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'设备控制',
style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
SizedBox(height: 20.h),
_buildMainPowerControl(),
SizedBox(height: 24.h),
Text(
'分设备控制',
style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
SizedBox(height: 20.h),
...controlDevices.asMap().entries.map((entry) {
final index = entry.key;
final device = entry.value;
return Padding(
padding: EdgeInsets.only(bottom: index < controlDevices.length - 1 ? 20.h : 0),
child: _buildDeviceControl(index, device),
);
}).toList(),
],
),
);
}
Widget _buildMainPowerControl() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 64.w,
height: 64.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(235, 244, 255, 1.0),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(
Icons.access_time_outlined,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 36.sp,
),
),
SizedBox(width: 16.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'房间总电源',
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
Text(
'控制整个房间供电',
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(100, 116, 139, 1.0),
),
),
],
),
],
),
FlutterSwitch(
value: mainPowerOn,
onToggle: onMainPowerToggle,
activeColor: const Color.fromRGBO(59, 130, 246, 1),
inactiveColor: const Color.fromRGBO(209, 213, 219, 1),
width: 60.w,
height: 30.h,
toggleSize: 26,
),
],
),
SizedBox(height: 20.h),
Divider(
color: const Color.fromRGBO(242, 243, 245, 1.0),
thickness: 1.h,
),
],
);
}
Widget _buildDeviceControl(int index, ControlDevice device) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
device.icon,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 36.sp,
),
SizedBox(width: 8.w),
Text(
device.name,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
],
),
if (device.detailText != null) ...[
SizedBox(height: 8.h),
Text(
device.detailText!,
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(100, 116, 139, 1.0),
),
),
],
],
),
),
FlutterSwitch(
value: device.isOn,
onToggle: (value) => onDeviceToggle(index, value),
activeColor: const Color.fromRGBO(66, 165, 245, 1.0),
inactiveColor: const Color.fromRGBO(200, 208, 220, 1.0),
width: 60.w,
height: 30.h,
toggleSize: 26,
),
],
),
if (index < controlDevices.length - 1) ...[
SizedBox(height: 20.h),
Divider(
color: const Color.fromRGBO(242, 243, 245, 1.0),
thickness: 1.h,
),
],
],
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class RoomBottomButtons extends StatelessWidget {
const RoomBottomButtons({super.key});
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: Container(
height: 88.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(66, 165, 245, 1.0),
borderRadius: BorderRadius.circular(20.r),
),
child: Center(
child: Text(
'送电',
style: TextStyle(
color: Colors.white,
fontSize: 32.sp,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(width: 12.w),
Expanded(
child: Container(
height: 88.h,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
border: Border.all(
color: const Color.fromRGBO(66, 165, 245, 1.0),
width: 2.w,
),
),
child: Center(
child: Text(
'断电',
style: TextStyle(
color: const Color.fromRGBO(66, 165, 245, 1.0),
fontSize: 32.sp,
fontWeight: FontWeight.bold,
),
),
),
),
),
SizedBox(width: 12.w),
Expanded(
child: Container(
height: 88.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(200, 208, 220, 1.0),
borderRadius: BorderRadius.circular(20.r),
),
child: Center(
child: Text(
'设备控制',
style: TextStyle(
color: const Color.fromRGBO(100, 116, 139, 1.0),
fontSize: 32.sp,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
class RoomDeviceStatusCard extends StatelessWidget {
final List<RoomDevice> devices;
const RoomDeviceStatusCard({
super.key,
required this.devices,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24.r),
),
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'房间设备状态',
style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
SizedBox(height: 20.h),
GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16.w,
mainAxisSpacing: 16.h,
childAspectRatio: 2,
),
itemCount: devices.length,
itemBuilder: (context, index) {
final device = devices[index];
return Container(
decoration: BoxDecoration(
color: const Color.fromRGBO(235, 244, 255, 1.0),
borderRadius: BorderRadius.circular(28.r),
),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
device.icon,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 36.sp,
),
SizedBox(width: 8.w),
Text(
device.name,
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(66, 165, 245, 1.0),
fontWeight: FontWeight.bold,
),
),
],
),
SizedBox(height: 12.h),
if (device.statusText != null)
Text(
device.statusText!,
style: TextStyle(
fontSize: 26.sp,
color: device.isOn
? const Color.fromRGBO(26, 188, 156, 1.0)
: const Color.fromRGBO(100, 116, 139, 1.0),
),
),
],
),
);
},
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
class RoomOverviewCard extends StatelessWidget {
final String roomNumber;
final String roomStatus;
final List<RoomStatusTag> statusTags;
const RoomOverviewCard({
super.key,
required this.roomNumber,
required this.roomStatus,
required this.statusTags,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24.r),
),
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 24.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 88.w,
height: 88.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(235, 244, 255, 1.0),
borderRadius: BorderRadius.circular(16.r),
),
child: Icon(
Icons.bed_outlined,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 48.sp,
),
),
SizedBox(width: 20.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
roomNumber,
style: TextStyle(
fontSize: 36.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
SizedBox(width: 12.w),
Text(
roomStatus,
style: TextStyle(
fontSize: 28.sp,
color: const Color.fromRGBO(66, 165, 245, 1.0),
),
),
],
),
],
),
],
),
SizedBox(height: 24.h),
Wrap(
spacing: 8.w,
children: statusTags.map((tag) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h),
decoration: BoxDecoration(
color: const Color.fromRGBO(225, 245, 238, 1.0),
borderRadius: BorderRadius.circular(12.r),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.check,
color: const Color.fromRGBO(26, 188, 156, 1.0),
size: 20.sp,
),
SizedBox(width: 4.w),
Text(
_getTagLabel(tag),
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(26, 188, 156, 1.0),
),
),
],
),
);
}).toList(),
),
],
),
);
}
String _getTagLabel(RoomStatusTag tag) {
switch (tag) {
case RoomStatusTag.hasPerson:
return '有人';
case RoomStatusTag.powerOn:
return '通电中';
case RoomStatusTag.wifiNormal:
return 'wifi正常';
}
}
}
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