Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
smart_hotel_app
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张宏
smart_hotel_app
Commits
5114f34f
Commit
5114f34f
authored
Jun 10, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
空调控制
parent
ea90a54a
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
484 additions
and
54 deletions
+484
-54
ac_bo.dart
lib/models/bo/ac_bo.dart
+153
-0
ac_repository.dart
lib/repositories/ac_repository.dart
+39
-0
app_router.gr.dart
lib/routes/app_router.gr.dart
+34
-5
ac_service.dart
lib/services/ac_service.dart
+37
-0
service_device_cubit.dart
lib/views/service/device/cubit/service_device_cubit.dart
+150
-31
service_device_state.dart
lib/views/service/device/cubit/service_device_state.dart
+23
-3
device_detail_view.dart
lib/views/service/device/device_detail_view.dart
+38
-13
service_room_cubit.dart
lib/views/service/room/cubit/service_room_cubit.dart
+4
-0
service_room_state.dart
lib/views/service/room/cubit/service_room_state.dart
+4
-0
room_detail_view.dart
lib/views/service/room/room_detail_view.dart
+2
-2
No files found.
lib/models/bo/ac_bo.dart
0 → 100644
View file @
5114f34f
import
'package:equatable/equatable.dart'
;
String
_parseString
(
dynamic
value
,
{
String
fallback
=
''
})
{
if
(
value
==
null
)
return
fallback
;
if
(
value
is
String
)
return
value
;
return
value
.
toString
();
}
int
_parseInt
(
dynamic
value
,
{
int
fallback
=
0
})
{
if
(
value
==
null
)
return
fallback
;
if
(
value
is
int
)
return
value
;
if
(
value
is
double
)
return
value
.
toInt
();
if
(
value
is
String
)
{
final
parsed
=
int
.
tryParse
(
value
.
trim
());
return
parsed
??
fallback
;
}
return
fallback
;
}
/// 空调状态 BO - 对应 GET /app/device/ac/status 响应
class
AcStatusBO
extends
Equatable
{
final
int
deviceId
;
final
String
deviceName
;
final
String
powerStatus
;
// 电源开关状态码:0=关闭 1=开启
final
String
currentTemperature
;
// 当前室内温度值
final
String
targetTemperature
;
// 目标设定温度值
final
String
mode
;
// 当前工作模式码:cooling/heating/dehumidify/fan/auto
final
String
modeText
;
// 工作模式中文文本
final
String
fanSpeed
;
// 当前风速档位码:low/mid/high/auto
final
String
fanSpeedText
;
// 风速中文文本
const
AcStatusBO
({
required
this
.
deviceId
,
required
this
.
deviceName
,
required
this
.
powerStatus
,
required
this
.
currentTemperature
,
required
this
.
targetTemperature
,
required
this
.
mode
,
required
this
.
modeText
,
required
this
.
fanSpeed
,
required
this
.
fanSpeedText
,
});
factory
AcStatusBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AcStatusBO
(
deviceId:
_parseInt
(
json
[
'deviceId'
]),
deviceName:
_parseString
(
json
[
'deviceName'
]),
powerStatus:
_parseString
(
json
[
'powerStatus'
]),
currentTemperature:
_parseString
(
json
[
'currentTemperature'
]),
targetTemperature:
_parseString
(
json
[
'targetTemperature'
]),
mode:
_parseString
(
json
[
'mode'
]),
modeText:
_parseString
(
json
[
'modeText'
]),
fanSpeed:
_parseString
(
json
[
'fanSpeed'
]),
fanSpeedText:
_parseString
(
json
[
'fanSpeedText'
]),
);
}
/// 电源是否开启
bool
get
isPowerOn
=>
powerStatus
==
'1'
;
/// 当前温度(int)
int
get
currentTempInt
=>
int
.
tryParse
(
currentTemperature
)
??
0
;
/// 目标温度(int)
int
get
targetTempInt
=>
int
.
tryParse
(
targetTemperature
)
??
24
;
@override
List
<
Object
?>
get
props
=>
[
deviceId
,
deviceName
,
powerStatus
,
currentTemperature
,
targetTemperature
,
mode
,
modeText
,
fanSpeed
,
fanSpeedText
,
];
}
/// Mode 映射工具
class
AcModeMapper
{
/// UI 模式名 → GET 返回的 mode 码
static
const
Map
<
String
,
String
>
uiToGetMode
=
{
'制冷'
:
'cooling'
,
'制热'
:
'heating'
,
'除湿'
:
'dehumidify'
,
'送风'
:
'fan'
,
'自动'
:
'auto'
,
};
/// GET 返回的 mode 码 → UI 模式名
static
const
Map
<
String
,
String
>
getToUiMode
=
{
'cooling'
:
'制冷'
,
'heating'
:
'制热'
,
'dehumidify'
:
'除湿'
,
'fan'
:
'送风'
,
'auto'
:
'自动'
,
};
/// UI 模式名 → POST 请求的 mode 码
static
const
Map
<
String
,
String
>
uiToPostMode
=
{
'制冷'
:
'cool'
,
'制热'
:
'heat'
,
'除湿'
:
'dry'
,
'送风'
:
'fan'
,
'自动'
:
'auto'
,
};
/// UI 风速名 → GET 返回的 API 风速码
static
const
Map
<
String
,
String
>
uiToGetFanSpeed
=
{
'自动'
:
'auto'
,
'低'
:
'low'
,
'中'
:
'mid'
,
'高'
:
'high'
,
};
/// GET 返回的 API 风速码 → UI 风速名
static
const
Map
<
String
,
String
>
getToUiFanSpeed
=
{
'auto'
:
'自动'
,
'low'
:
'低'
,
'mid'
:
'中'
,
'high'
:
'高'
,
};
/// UI 风速名 → POST 请求的 API 风速码(注意:POST 用 medium,GET 用 mid)
static
const
Map
<
String
,
String
>
uiToPostFanSpeed
=
{
'自动'
:
'auto'
,
'低'
:
'low'
,
'中'
:
'medium'
,
'高'
:
'high'
,
};
/// 根据 GET mode 码获取 UI 模式名,未知时返回原值
static
String
modeTextFromCode
(
String
modeCode
)
{
return
getToUiMode
[
modeCode
]
??
modeCode
;
}
/// 根据 UI 模式名获取 POST mode 码
static
String
postModeFromUi
(
String
uiModeName
)
{
return
uiToPostMode
[
uiModeName
]
??
'cool'
;
}
/// 根据 GET 风速码获取 UI 风速名
static
String
fanSpeedTextFromGetCode
(
String
fanSpeedCode
)
{
return
getToUiFanSpeed
[
fanSpeedCode
]
??
fanSpeedCode
;
}
/// 根据 UI 风速名获取 POST 风速码
static
String
postFanSpeedFromUi
(
String
uiFanSpeedName
)
{
return
uiToPostFanSpeed
[
uiFanSpeedName
]
??
'auto'
;
}
}
lib/repositories/ac_repository.dart
0 → 100644
View file @
5114f34f
import
'../utils/http/response_model.dart'
;
import
'../utils/http/dio_request.dart'
;
import
'../models/bo/ac_bo.dart'
;
class
AcRepository
{
/// 获取空调状态
/// GET /app/device/ac/status
Future
<
ResponseModel
<
AcStatusBO
>>
getStatus
({
required
int
deviceId
})
{
return
DioRequest
.
instance
.
get
<
AcStatusBO
>(
'/app/device/ac/status'
,
queryParameters:
{
'deviceId'
:
deviceId
},
fromJsonT:
(
data
)
=>
AcStatusBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
}
/// 空调控制操作
/// POST /app/device/ac/control
Future
<
ResponseModel
<
Map
<
String
,
dynamic
>>>
control
({
required
int
deviceId
,
bool
?
powerOn
,
int
?
targetTemperature
,
String
?
mode
,
String
?
fanSpeed
,
})
{
final
params
=
<
String
,
dynamic
>{
'deviceId'
:
deviceId
,
};
if
(
powerOn
!=
null
)
params
[
'powerOn'
]
=
powerOn
;
if
(
targetTemperature
!=
null
)
params
[
'targetTemperature'
]
=
targetTemperature
;
if
(
mode
!=
null
)
params
[
'mode'
]
=
mode
;
if
(
fanSpeed
!=
null
)
params
[
'fanSpeed'
]
=
fanSpeed
;
return
DioRequest
.
instance
.
post
<
Map
<
String
,
dynamic
>>(
'/app/device/ac/control'
,
data:
params
,
);
}
}
lib/routes/app_router.gr.dart
View file @
5114f34f
...
@@ -181,9 +181,14 @@ abstract class $AppRouter extends _i21.RootStackRouter {
...
@@ -181,9 +181,14 @@ abstract class $AppRouter extends _i21.RootStackRouter {
);
);
},
},
ServiceDeviceDetailRoute
.
name
:
(
routeData
)
{
ServiceDeviceDetailRoute
.
name
:
(
routeData
)
{
final
args
=
routeData
.
argsAs
<
ServiceDeviceDetailRouteArgs
>(
orElse:
()
=>
const
ServiceDeviceDetailRouteArgs
(
deviceId:
0
));
return
_i21
.
AutoRoutePage
<
dynamic
>(
return
_i21
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i18
.
ServiceDeviceDetailView
(),
child:
_i18
.
ServiceDeviceDetailView
(
key:
args
.
key
,
deviceId:
args
.
deviceId
,
),
);
);
},
},
ServiceIndexRoute
.
name
:
(
routeData
)
{
ServiceIndexRoute
.
name
:
(
routeData
)
{
...
@@ -586,16 +591,40 @@ class SearchRouteArgs {
...
@@ -586,16 +591,40 @@ class SearchRouteArgs {
/// generated route for
/// generated route for
/// [_i18.ServiceDeviceDetailView]
/// [_i18.ServiceDeviceDetailView]
class
ServiceDeviceDetailRoute
extends
_i21
.
PageRouteInfo
<
void
>
{
class
ServiceDeviceDetailRoute
extends
_i21
.
PageRouteInfo
<
ServiceDeviceDetailRouteArgs
>
{
const
ServiceDeviceDetailRoute
({
List
<
_i21
.
PageRouteInfo
>?
children
})
ServiceDeviceDetailRoute
({
:
super
(
_i22
.
Key
?
key
,
required
int
deviceId
,
List
<
_i21
.
PageRouteInfo
>?
children
,
})
:
super
(
ServiceDeviceDetailRoute
.
name
,
ServiceDeviceDetailRoute
.
name
,
args:
ServiceDeviceDetailRouteArgs
(
key:
key
,
deviceId:
deviceId
,
),
initialChildren:
children
,
initialChildren:
children
,
);
);
static
const
String
name
=
'ServiceDeviceDetailRoute'
;
static
const
String
name
=
'ServiceDeviceDetailRoute'
;
static
const
_i21
.
PageInfo
<
void
>
page
=
_i21
.
PageInfo
<
void
>(
name
);
static
const
_i21
.
PageInfo
<
ServiceDeviceDetailRouteArgs
>
page
=
_i21
.
PageInfo
<
ServiceDeviceDetailRouteArgs
>(
name
);
}
class
ServiceDeviceDetailRouteArgs
{
const
ServiceDeviceDetailRouteArgs
({
this
.
key
,
required
this
.
deviceId
,
});
final
_i22
.
Key
?
key
;
final
int
deviceId
;
@override
String
toString
()
{
return
'ServiceDeviceDetailRouteArgs{key:
$key
, deviceId:
$deviceId
}'
;
}
}
}
/// generated route for
/// generated route for
...
...
lib/services/ac_service.dart
0 → 100644
View file @
5114f34f
import
'../models/bo/ac_bo.dart'
;
import
'../repositories/ac_repository.dart'
;
class
AcService
{
final
AcRepository
_repository
;
AcService
({
required
AcRepository
repository
})
:
_repository
=
repository
;
/// 获取空调状态
Future
<
AcStatusBO
>
getStatus
({
required
int
deviceId
})
async
{
final
result
=
await
_repository
.
getStatus
(
deviceId:
deviceId
);
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
}
throw
Exception
(
result
.
msg
);
}
/// 空调控制操作
Future
<
void
>
control
({
required
int
deviceId
,
bool
?
powerOn
,
int
?
targetTemperature
,
String
?
mode
,
String
?
fanSpeed
,
})
async
{
final
result
=
await
_repository
.
control
(
deviceId:
deviceId
,
powerOn:
powerOn
,
targetTemperature:
targetTemperature
,
mode:
mode
,
fanSpeed:
fanSpeed
,
);
if
(!
result
.
success
)
{
throw
Exception
(
result
.
msg
);
}
}
}
lib/views/service/device/cubit/service_device_cubit.dart
View file @
5114f34f
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:smart_hotel_app/models/bo/ac_bo.dart'
;
import
'package:smart_hotel_app/repositories/ac_repository.dart'
;
import
'package:smart_hotel_app/services/ac_service.dart'
;
import
'package:smart_hotel_app/views/service/device/cubit/service_device_state.dart'
;
import
'package:smart_hotel_app/views/service/device/cubit/service_device_state.dart'
;
class
ServiceDeviceCubit
extends
Cubit
<
ServiceDeviceState
>
{
class
ServiceDeviceCubit
extends
Cubit
<
ServiceDeviceState
>
{
ServiceDeviceCubit
()
:
super
(
const
ServiceDeviceState
())
{
final
AcService
_service
;
initData
();
final
int
_deviceId
;
ServiceDeviceCubit
({
AcService
?
service
,
required
int
deviceId
,
})
:
_service
=
service
??
AcService
(
repository:
AcRepository
()),
_deviceId
=
deviceId
,
super
(
ServiceDeviceState
(
deviceId:
deviceId
))
{
loadAcStatus
();
}
/// 加载空调状态
Future
<
void
>
loadAcStatus
()
async
{
emit
(
state
.
copyWith
(
isLoading:
true
,
clearError:
true
));
try
{
final
status
=
await
_service
.
getStatus
(
deviceId:
_deviceId
);
emit
(
_mapStatusToState
(
status
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
}
}
}
void
initData
()
{
/// 将 API 返回的 AcStatusBO 映射为 State
emit
(
state
.
copyWith
(
ServiceDeviceState
_mapStatusToState
(
AcStatusBO
status
)
{
isOn:
true
,
// 构建模式数据列表
targetTemperature:
24
,
const
allModes
=
[
'制冷'
,
'制热'
,
'除湿'
,
'送风'
];
currentTemperature:
26
,
final
currentModeName
=
AcModeMapper
.
modeTextFromCode
(
status
.
mode
);
final
modeData
=
allModes
.
map
((
name
)
{
return
{
'name'
:
name
,
'icon'
:
_modeIcon
(
name
),
'isSelected'
:
name
==
currentModeName
,
};
}).
toList
();
// 解析温度
final
currentTemp
=
status
.
currentTempInt
;
final
targetTemp
=
status
.
targetTempInt
;
// 获取当前风速的 UI 名称
final
currentSpeed
=
AcModeMapper
.
fanSpeedTextFromGetCode
(
status
.
fanSpeed
);
return
ServiceDeviceState
(
isLoading:
false
,
deviceId:
_deviceId
,
isOn:
status
.
isPowerOn
,
currentTemperature:
currentTemp
>
0
?
currentTemp
:
26
,
targetTemperature:
targetTemp
>
0
?
targetTemp
:
24
,
minTemperature:
16
,
minTemperature:
16
,
maxTemperature:
34
,
maxTemperature:
30
,
modeData:
[
modeData:
modeData
,
{
'name'
:
'制冷'
,
'icon'
:
Icons
.
ac_unit
,
'isSelected'
:
true
},
currentSpeed:
currentSpeed
,
{
'name'
:
'制热'
,
'icon'
:
Icons
.
heat_pump
,
'isSelected'
:
false
},
speedOptions:
const
[
'自动'
,
'低'
,
'中'
,
'高'
],
{
'name'
:
'除湿'
,
'icon'
:
Icons
.
water_drop
,
'isSelected'
:
false
},
);
{
'name'
:
'送风'
,
'icon'
:
Icons
.
air
,
'isSelected'
:
false
},
],
currentSpeed:
'自动'
,
speedOptions:
[
'自动'
,
'低'
,
'中'
,
'高'
],
));
}
}
void
togglePower
(
bool
value
)
{
/// 获取模式对应的图标
emit
(
state
.
copyWith
(
isOn:
value
));
IconData
_modeIcon
(
String
modeName
)
{
switch
(
modeName
)
{
case
'制冷'
:
return
Icons
.
ac_unit
;
case
'制热'
:
return
Icons
.
heat_pump
;
case
'除湿'
:
return
Icons
.
water_drop
;
case
'送风'
:
return
Icons
.
air
;
default
:
return
Icons
.
ac_unit
;
}
}
}
void
setTargetTemperature
(
int
temp
)
{
/// 开关机
if
(
temp
>=
state
.
minTemperature
&&
temp
<=
state
.
maxTemperature
)
{
Future
<
void
>
togglePower
(
bool
value
)
async
{
emit
(
state
.
copyWith
(
targetTemperature:
temp
));
if
(
state
.
isOperating
)
return
;
// 乐观更新 UI
final
previousState
=
state
;
emit
(
state
.
copyWith
(
isOn:
value
,
isOperating:
true
));
try
{
await
_service
.
control
(
deviceId:
_deviceId
,
powerOn:
value
,
);
emit
(
state
.
copyWith
(
isOperating:
false
));
}
catch
(
e
)
{
// 失败时回滚状态
emit
(
previousState
.
copyWith
(
isOperating:
false
,
error:
e
.
toString
(),
));
}
}
/// 设置目标温度
Future
<
void
>
_setTargetTemperature
(
int
temp
)
async
{
if
(
state
.
isOperating
)
return
;
if
(
temp
<
state
.
minTemperature
||
temp
>
state
.
maxTemperature
)
return
;
final
previousState
=
state
;
emit
(
state
.
copyWith
(
targetTemperature:
temp
,
isOperating:
true
));
try
{
await
_service
.
control
(
deviceId:
_deviceId
,
targetTemperature:
temp
,
);
emit
(
state
.
copyWith
(
isOperating:
false
));
}
catch
(
e
)
{
emit
(
previousState
.
copyWith
(
isOperating:
false
,
error:
e
.
toString
(),
));
}
}
}
}
void
increaseTemperature
()
{
void
increaseTemperature
()
{
if
(
state
.
targetTemperature
<
state
.
maxTemperature
)
{
if
(
state
.
targetTemperature
<
state
.
maxTemperature
)
{
emit
(
state
.
copyWith
(
targetTemperature:
state
.
targetTemperature
+
1
)
);
_setTargetTemperature
(
state
.
targetTemperature
+
1
);
}
}
}
}
void
decreaseTemperature
()
{
void
decreaseTemperature
()
{
if
(
state
.
targetTemperature
>
state
.
minTemperature
)
{
if
(
state
.
targetTemperature
>
state
.
minTemperature
)
{
emit
(
state
.
copyWith
(
targetTemperature:
state
.
targetTemperature
-
1
)
);
_setTargetTemperature
(
state
.
targetTemperature
-
1
);
}
}
}
}
void
selectMode
(
int
index
)
{
/// 选择模式
Future
<
void
>
selectMode
(
int
index
)
async
{
if
(
state
.
isOperating
)
return
;
if
(
index
<
0
||
index
>=
state
.
modeData
.
length
)
return
;
final
previousState
=
state
;
final
updatedModeData
=
state
.
modeData
.
map
((
mode
)
{
final
updatedModeData
=
state
.
modeData
.
map
((
mode
)
{
return
{...
mode
,
'isSelected'
:
false
};
return
{...
mode
,
'isSelected'
:
false
};
}).
toList
();
}).
toList
();
updatedModeData
[
index
][
'isSelected'
]
=
true
;
updatedModeData
[
index
][
'isSelected'
]
=
true
;
emit
(
state
.
copyWith
(
modeData:
updatedModeData
));
final
modeName
=
updatedModeData
[
index
][
'name'
]
as
String
;
emit
(
state
.
copyWith
(
modeData:
updatedModeData
,
isOperating:
true
));
try
{
await
_service
.
control
(
deviceId:
_deviceId
,
mode:
AcModeMapper
.
postModeFromUi
(
modeName
),
);
emit
(
state
.
copyWith
(
isOperating:
false
));
}
catch
(
e
)
{
emit
(
previousState
.
copyWith
(
isOperating:
false
,
error:
e
.
toString
(),
));
}
}
}
void
setWindSpeed
(
String
speed
)
{
/// 设置风速
emit
(
state
.
copyWith
(
currentSpeed:
speed
));
Future
<
void
>
setWindSpeed
(
String
speed
)
async
{
if
(
state
.
isOperating
)
return
;
final
previousState
=
state
;
emit
(
state
.
copyWith
(
currentSpeed:
speed
,
isOperating:
true
));
try
{
await
_service
.
control
(
deviceId:
_deviceId
,
fanSpeed:
AcModeMapper
.
postFanSpeedFromUi
(
speed
),
);
emit
(
state
.
copyWith
(
isOperating:
false
));
}
catch
(
e
)
{
emit
(
previousState
.
copyWith
(
isOperating:
false
,
error:
e
.
toString
(),
));
}
}
}
}
}
\ No newline at end of file
lib/views/service/device/cubit/service_device_state.dart
View file @
5114f34f
import
'package:equatable/equatable.dart'
;
import
'package:equatable/equatable.dart'
;
class
ServiceDeviceState
extends
Equatable
{
class
ServiceDeviceState
extends
Equatable
{
final
bool
isLoading
;
final
String
?
error
;
final
bool
isOperating
;
// 操作进行中(防重复提交)
final
int
deviceId
;
final
bool
isOn
;
final
bool
isOn
;
final
int
targetTemperature
;
final
int
targetTemperature
;
final
int
currentTemperature
;
final
int
currentTemperature
;
...
@@ -11,17 +15,25 @@ class ServiceDeviceState extends Equatable {
...
@@ -11,17 +15,25 @@ class ServiceDeviceState extends Equatable {
final
List
<
String
>
speedOptions
;
final
List
<
String
>
speedOptions
;
const
ServiceDeviceState
({
const
ServiceDeviceState
({
this
.
isLoading
=
false
,
this
.
error
,
this
.
isOperating
=
false
,
this
.
deviceId
=
0
,
this
.
isOn
=
true
,
this
.
isOn
=
true
,
this
.
targetTemperature
=
24
,
this
.
targetTemperature
=
24
,
this
.
currentTemperature
=
26
,
this
.
currentTemperature
=
26
,
this
.
minTemperature
=
16
,
this
.
minTemperature
=
16
,
this
.
maxTemperature
=
3
4
,
this
.
maxTemperature
=
3
0
,
this
.
modeData
=
const
[],
this
.
modeData
=
const
[],
this
.
currentSpeed
=
'自动'
,
this
.
currentSpeed
=
'自动'
,
this
.
speedOptions
=
const
[
'自动'
,
'低'
,
'中'
,
'高'
],
this
.
speedOptions
=
const
[
'自动'
,
'低'
,
'中'
,
'高'
],
});
});
ServiceDeviceState
copyWith
({
ServiceDeviceState
copyWith
({
bool
?
isLoading
,
String
?
error
,
bool
?
isOperating
,
int
?
deviceId
,
bool
?
isOn
,
bool
?
isOn
,
int
?
targetTemperature
,
int
?
targetTemperature
,
int
?
currentTemperature
,
int
?
currentTemperature
,
...
@@ -30,8 +42,13 @@ class ServiceDeviceState extends Equatable {
...
@@ -30,8 +42,13 @@ class ServiceDeviceState extends Equatable {
List
<
Map
<
String
,
dynamic
>>?
modeData
,
List
<
Map
<
String
,
dynamic
>>?
modeData
,
String
?
currentSpeed
,
String
?
currentSpeed
,
List
<
String
>?
speedOptions
,
List
<
String
>?
speedOptions
,
bool
clearError
=
false
,
})
{
})
{
return
ServiceDeviceState
(
return
ServiceDeviceState
(
isLoading:
isLoading
??
this
.
isLoading
,
error:
clearError
?
null
:
(
error
??
this
.
error
),
isOperating:
isOperating
??
this
.
isOperating
,
deviceId:
deviceId
??
this
.
deviceId
,
isOn:
isOn
??
this
.
isOn
,
isOn:
isOn
??
this
.
isOn
,
targetTemperature:
targetTemperature
??
this
.
targetTemperature
,
targetTemperature:
targetTemperature
??
this
.
targetTemperature
,
currentTemperature:
currentTemperature
??
this
.
currentTemperature
,
currentTemperature:
currentTemperature
??
this
.
currentTemperature
,
...
@@ -45,6 +62,10 @@ class ServiceDeviceState extends Equatable {
...
@@ -45,6 +62,10 @@ class ServiceDeviceState extends Equatable {
@override
@override
List
<
Object
?>
get
props
=>
[
List
<
Object
?>
get
props
=>
[
isLoading
,
error
,
isOperating
,
deviceId
,
isOn
,
isOn
,
targetTemperature
,
targetTemperature
,
currentTemperature
,
currentTemperature
,
...
@@ -54,4 +75,4 @@ class ServiceDeviceState extends Equatable {
...
@@ -54,4 +75,4 @@ class ServiceDeviceState extends Equatable {
currentSpeed
,
currentSpeed
,
speedOptions
,
speedOptions
,
];
];
}
}
\ No newline at end of file
lib/views/service/device/device_detail_view.dart
View file @
5114f34f
...
@@ -10,12 +10,14 @@ import 'package:smart_hotel_app/views/service/device/widget/wind_speed_block.dar
...
@@ -10,12 +10,14 @@ import 'package:smart_hotel_app/views/service/device/widget/wind_speed_block.dar
@RoutePage
()
@RoutePage
()
class
ServiceDeviceDetailView
extends
StatelessWidget
{
class
ServiceDeviceDetailView
extends
StatelessWidget
{
const
ServiceDeviceDetailView
({
super
.
key
});
final
int
deviceId
;
const
ServiceDeviceDetailView
({
super
.
key
,
required
this
.
deviceId
});
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
return
BlocProvider
(
create:
(
_
)
=>
ServiceDeviceCubit
(),
create:
(
_
)
=>
ServiceDeviceCubit
(
deviceId:
deviceId
),
child:
Scaffold
(
child:
Scaffold
(
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
appBar:
AppBar
(
appBar:
AppBar
(
...
@@ -38,12 +40,36 @@ class ServiceDeviceDetailView extends StatelessWidget {
...
@@ -38,12 +40,36 @@ class ServiceDeviceDetailView extends StatelessWidget {
),
),
centerTitle:
true
,
centerTitle:
true
,
),
),
body:
SingleChildScrollView
(
body:
BlocBuilder
<
ServiceDeviceCubit
,
ServiceDeviceState
>(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
builder:
(
context
,
state
)
{
child:
BlocBuilder
<
ServiceDeviceCubit
,
ServiceDeviceState
>(
final
cubit
=
context
.
read
<
ServiceDeviceCubit
>();
builder:
(
context
,
state
)
{
if
(
state
.
isLoading
)
{
final
cubit
=
context
.
read
<
ServiceDeviceCubit
>();
return
const
Center
(
child:
CircularProgressIndicator
());
return
Column
(
}
if
(
state
.
error
!=
null
)
{
return
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
'加载失败:
${state.error}
'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
SizedBox
(
height:
16
.
h
),
ElevatedButton
(
onPressed:
()
=>
cubit
.
loadAcStatus
(),
child:
const
Text
(
'重试'
),
),
],
),
);
}
return
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
children:
[
children:
[
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
TemperatureControlBlock
(
TemperatureControlBlock
(
...
@@ -69,11 +95,11 @@ class ServiceDeviceDetailView extends StatelessWidget {
...
@@ -69,11 +95,11 @@ class ServiceDeviceDetailView extends StatelessWidget {
),
),
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
],
],
)
;
)
,
},
);
)
,
}
,
),
),
),
),
);
);
}
}
}
}
\ No newline at end of file
lib/views/service/room/cubit/service_room_cubit.dart
View file @
5114f34f
...
@@ -49,10 +49,12 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
...
@@ -49,10 +49,12 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
final
controlDevices
=
detail
.
deviceControl
.
subDeviceControls
.
map
((
c
)
{
final
controlDevices
=
detail
.
deviceControl
.
subDeviceControls
.
map
((
c
)
{
return
ControlDevice
(
return
ControlDevice
(
deviceId:
c
.
deviceId
,
name:
c
.
deviceName
,
name:
c
.
deviceName
,
icon:
_mapDeviceIcon
(
c
.
deviceTypeName
,
''
),
icon:
_mapDeviceIcon
(
c
.
deviceTypeName
,
''
),
isOn:
c
.
powerOn
,
isOn:
c
.
powerOn
,
detailText:
c
.
currentParamDisplay
.
isNotEmpty
?
c
.
currentParamDisplay
:
null
,
detailText:
c
.
currentParamDisplay
.
isNotEmpty
?
c
.
currentParamDisplay
:
null
,
deviceTypeName:
c
.
deviceTypeName
,
);
);
}).
toList
();
}).
toList
();
...
@@ -192,10 +194,12 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
...
@@ -192,10 +194,12 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
// navigates to ServiceDeviceDetailRoute for AC control.
// navigates to ServiceDeviceDetailRoute for AC control.
final
updatedDevices
=
List
<
ControlDevice
>.
from
(
devices
);
final
updatedDevices
=
List
<
ControlDevice
>.
from
(
devices
);
updatedDevices
[
index
]
=
ControlDevice
(
updatedDevices
[
index
]
=
ControlDevice
(
deviceId:
updatedDevices
[
index
].
deviceId
,
name:
updatedDevices
[
index
].
name
,
name:
updatedDevices
[
index
].
name
,
icon:
updatedDevices
[
index
].
icon
,
icon:
updatedDevices
[
index
].
icon
,
isOn:
value
,
isOn:
value
,
detailText:
updatedDevices
[
index
].
detailText
,
detailText:
updatedDevices
[
index
].
detailText
,
deviceTypeName:
updatedDevices
[
index
].
deviceTypeName
,
);
);
emit
(
state
.
copyWith
(
controlDevices:
updatedDevices
));
emit
(
state
.
copyWith
(
controlDevices:
updatedDevices
));
}
}
...
...
lib/views/service/room/cubit/service_room_state.dart
View file @
5114f34f
...
@@ -18,16 +18,20 @@ class RoomDevice {
...
@@ -18,16 +18,20 @@ class RoomDevice {
}
}
class
ControlDevice
{
class
ControlDevice
{
final
int
deviceId
;
final
String
name
;
final
String
name
;
final
IconData
icon
;
final
IconData
icon
;
final
bool
isOn
;
final
bool
isOn
;
final
String
?
detailText
;
final
String
?
detailText
;
final
String
?
deviceTypeName
;
const
ControlDevice
({
const
ControlDevice
({
this
.
deviceId
=
0
,
required
this
.
name
,
required
this
.
name
,
required
this
.
icon
,
required
this
.
icon
,
this
.
isOn
=
false
,
this
.
isOn
=
false
,
this
.
detailText
,
this
.
detailText
,
this
.
deviceTypeName
,
});
});
}
}
...
...
lib/views/service/room/room_detail_view.dart
View file @
5114f34f
...
@@ -122,8 +122,8 @@ class ServiceRoomDetailView extends StatelessWidget {
...
@@ -122,8 +122,8 @@ class ServiceRoomDetailView extends StatelessWidget {
onDeviceToggle:
(
index
,
value
)
=>
onDeviceToggle:
(
index
,
value
)
=>
cubit
.
toggleControlDevice
(
index
,
value
),
cubit
.
toggleControlDevice
(
index
,
value
),
onDeviceTap:
(
index
,
device
)
{
onDeviceTap:
(
index
,
device
)
{
if
(
device
.
name
==
'空调'
)
{
if
(
device
.
deviceTypeName
==
'空调'
||
device
.
deviceTypeName
?.
contains
(
'空调'
)
==
true
)
{
context
.
pushRoute
(
const
ServiceDeviceDetailRoute
(
));
context
.
pushRoute
(
ServiceDeviceDetailRoute
(
deviceId:
device
.
deviceId
));
}
}
},
},
),
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment