Commit 14c26670 authored by 张宏's avatar 张宏

3333

parent 70c95cd5
...@@ -24,13 +24,15 @@ class DeviceTopologyInfoBO { ...@@ -24,13 +24,15 @@ class DeviceTopologyInfoBO {
final int deviceId; final int deviceId;
final String deviceName; final String deviceName;
final String deviceCode; final String deviceCode;
final String locationText; final String deviceLocation;
final String statusText;
const DeviceTopologyInfoBO({ const DeviceTopologyInfoBO({
required this.deviceId, required this.deviceId,
required this.deviceName, required this.deviceName,
required this.deviceCode, required this.deviceCode,
required this.locationText, required this.deviceLocation,
required this.statusText
}); });
factory DeviceTopologyInfoBO.fromJson(Map<String, dynamic> json) { factory DeviceTopologyInfoBO.fromJson(Map<String, dynamic> json) {
...@@ -38,7 +40,8 @@ class DeviceTopologyInfoBO { ...@@ -38,7 +40,8 @@ class DeviceTopologyInfoBO {
deviceId: json['deviceId'] as int? ?? 0, deviceId: json['deviceId'] as int? ?? 0,
deviceName: json['deviceName'] as String? ?? '', deviceName: json['deviceName'] as String? ?? '',
deviceCode: json['deviceCode'] as String? ?? '', deviceCode: json['deviceCode'] as String? ?? '',
locationText: json['locationText'] as String? ?? '', deviceLocation: json['deviceLocation'] as String? ?? '',
statusText: json['statusText'] as String? ?? ''
); );
} }
} }
...@@ -51,6 +54,7 @@ class TreeNodeBO { ...@@ -51,6 +54,7 @@ class TreeNodeBO {
final String status; final String status;
final String statusText; final String statusText;
final String deviceCode; final String deviceCode;
final int? gatewayId;
const TreeNodeBO({ const TreeNodeBO({
required this.deviceId, required this.deviceId,
...@@ -60,6 +64,7 @@ class TreeNodeBO { ...@@ -60,6 +64,7 @@ class TreeNodeBO {
required this.status, required this.status,
required this.statusText, required this.statusText,
required this.deviceCode, required this.deviceCode,
this.gatewayId,
}); });
factory TreeNodeBO.fromJson(Map<String, dynamic> json) { factory TreeNodeBO.fromJson(Map<String, dynamic> json) {
...@@ -71,6 +76,7 @@ class TreeNodeBO { ...@@ -71,6 +76,7 @@ class TreeNodeBO {
status: json['status'] as String? ?? '', status: json['status'] as String? ?? '',
statusText: json['statusText'] as String? ?? '', statusText: json['statusText'] as String? ?? '',
deviceCode: json['deviceCode'] as String? ?? '', deviceCode: json['deviceCode'] as String? ?? '',
gatewayId: json['gatewayId'] as int?,
); );
} }
} }
\ No newline at end of file
...@@ -63,10 +63,15 @@ class DeviceCubit extends Cubit<DeviceState> { ...@@ -63,10 +63,15 @@ class DeviceCubit extends Cubit<DeviceState> {
emit(state.copyWith(isPoweringOn: true)); emit(state.copyWith(isPoweringOn: true));
try { try {
await _service.powerOn(deviceId: _deviceId); await _service.powerOn(deviceId: _deviceId);
emit(state.copyWith(isPoweringOn: false)); emit(state.copyWith(
isPoweringOn: false,
operationMessage: '远程送电成功',
));
} catch (e) { } catch (e) {
emit(state.copyWith(isPoweringOn: false)); emit(state.copyWith(
rethrow; isPoweringOn: false,
operationMessage: '远程送电失败: $e',
));
} }
} }
...@@ -75,10 +80,19 @@ class DeviceCubit extends Cubit<DeviceState> { ...@@ -75,10 +80,19 @@ class DeviceCubit extends Cubit<DeviceState> {
emit(state.copyWith(isPoweringOff: true)); emit(state.copyWith(isPoweringOff: true));
try { try {
await _service.powerOff(deviceId: _deviceId); await _service.powerOff(deviceId: _deviceId);
emit(state.copyWith(isPoweringOff: false)); emit(state.copyWith(
isPoweringOff: false,
operationMessage: '远程断电成功',
));
} catch (e) { } catch (e) {
emit(state.copyWith(isPoweringOff: false)); emit(state.copyWith(
rethrow; isPoweringOff: false,
operationMessage: '远程断电失败: $e',
));
} }
} }
void clearOperationMessage() {
emit(state.copyWith(operationMessage: null));
}
} }
\ No newline at end of file
...@@ -30,6 +30,7 @@ class DeviceState { ...@@ -30,6 +30,7 @@ class DeviceState {
final DeviceInfo? deviceInfo; final DeviceInfo? deviceInfo;
final bool isPoweringOn; final bool isPoweringOn;
final bool isPoweringOff; final bool isPoweringOff;
final String? operationMessage;
const DeviceState({ const DeviceState({
this.isLoading = false, this.isLoading = false,
...@@ -37,6 +38,7 @@ class DeviceState { ...@@ -37,6 +38,7 @@ class DeviceState {
this.deviceInfo, this.deviceInfo,
this.isPoweringOn = false, this.isPoweringOn = false,
this.isPoweringOff = false, this.isPoweringOff = false,
this.operationMessage,
}); });
DeviceState copyWith({ DeviceState copyWith({
...@@ -45,6 +47,7 @@ class DeviceState { ...@@ -45,6 +47,7 @@ class DeviceState {
DeviceInfo? deviceInfo, DeviceInfo? deviceInfo,
bool? isPoweringOn, bool? isPoweringOn,
bool? isPoweringOff, bool? isPoweringOff,
String? operationMessage,
}) { }) {
return DeviceState( return DeviceState(
isLoading: isLoading ?? this.isLoading, isLoading: isLoading ?? this.isLoading,
...@@ -52,6 +55,7 @@ class DeviceState { ...@@ -52,6 +55,7 @@ class DeviceState {
deviceInfo: deviceInfo ?? this.deviceInfo, deviceInfo: deviceInfo ?? this.deviceInfo,
isPoweringOn: isPoweringOn ?? this.isPoweringOn, isPoweringOn: isPoweringOn ?? this.isPoweringOn,
isPoweringOff: isPoweringOff ?? this.isPoweringOff, isPoweringOff: isPoweringOff ?? this.isPoweringOff,
operationMessage: operationMessage ?? this.operationMessage,
); );
} }
} }
\ No newline at end of file
...@@ -18,65 +18,76 @@ class DeviceDetailView extends StatelessWidget { ...@@ -18,65 +18,76 @@ class DeviceDetailView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (_) => DeviceCubit(deviceId: deviceId), create: (_) => DeviceCubit(deviceId: deviceId),
child: Scaffold( child: BlocListener<DeviceCubit, DeviceState>(
backgroundColor: const Color.fromRGBO(242, 243, 245, 1), listener: (context, state) {
appBar: AppBar( final message = state.operationMessage;
backgroundColor: Colors.white, if (message != null) {
elevation: 0, ScaffoldMessenger.of(context).showSnackBar(
leading: IconButton( SnackBar(content: Text(message)),
icon: const Icon(Icons.arrow_back_ios, );
color: Color.fromRGBO(100, 116, 139, 1)), context.read<DeviceCubit>().clearOperationMessage();
onPressed: () { }
context.popRoute(); },
}, child: Scaffold(
), backgroundColor: const Color.fromRGBO(242, 243, 245, 1),
title: Text( appBar: AppBar(
'设备控制', backgroundColor: Colors.white,
style: TextStyle( elevation: 0,
color: const Color.fromRGBO(10, 13, 20, 1), leading: IconButton(
fontSize: 32.sp, icon: const Icon(Icons.arrow_back_ios,
fontWeight: FontWeight.w200, color: Color.fromRGBO(100, 116, 139, 1)),
onPressed: () {
context.maybePop();
},
),
title: Text(
'设备控制',
style: TextStyle(
color: const Color.fromRGBO(10, 13, 20, 1),
fontSize: 32.sp,
fontWeight: FontWeight.w200,
),
), ),
centerTitle: true,
), ),
centerTitle: true, body: BlocBuilder<DeviceCubit, DeviceState>(
), builder: (context, state) {
body: BlocBuilder<DeviceCubit, DeviceState>( if (state.isLoading) {
builder: (context, state) { return const Center(child: CircularProgressIndicator());
if (state.isLoading) { }
return const Center(child: CircularProgressIndicator()); if (state.error != null) {
} return Center(
if (state.error != null) { child: Text(
return Center( '加载失败: ${state.error}',
child: Text( style: TextStyle(
'加载失败: ${state.error}', fontSize: 28.sp,
style: TextStyle( color: const Color.fromRGBO(255, 100, 101, 1),
fontSize: 28.sp, ),
color: const Color.fromRGBO(255, 100, 101, 1),
), ),
);
}
final deviceInfo = state.deviceInfo;
if (deviceInfo == null) {
return const SizedBox.shrink();
}
final cubit = context.read<DeviceCubit>();
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
StateInfoBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
DeviceParmsBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
PowerCharBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
_buildBottomButtons(context, cubit, state),
SizedBox(height: 30.h),
],
), ),
); );
} },
final deviceInfo = state.deviceInfo; ),
if (deviceInfo == null) {
return const SizedBox.shrink();
}
final cubit = context.read<DeviceCubit>();
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: Column(
children: [
StateInfoBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
DeviceParmsBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
PowerCharBlock(deviceInfo: deviceInfo),
SizedBox(height: 10.h),
_buildBottomButtons(context, cubit, state),
SizedBox(height: 30.h),
],
),
);
},
), ),
), ),
); );
...@@ -103,7 +114,7 @@ class DeviceDetailView extends StatelessWidget { ...@@ -103,7 +114,7 @@ class DeviceDetailView extends StatelessWidget {
child: TextButton( child: TextButton(
onPressed: state.isPoweringOn onPressed: state.isPoweringOn
? null ? null
: () => _handlePowerOn(context, cubit), : () => cubit.remotePowerOn(),
child: state.isPoweringOn child: state.isPoweringOn
? SizedBox( ? SizedBox(
width: 32.sp, width: 32.sp,
...@@ -140,7 +151,7 @@ class DeviceDetailView extends StatelessWidget { ...@@ -140,7 +151,7 @@ class DeviceDetailView extends StatelessWidget {
child: TextButton( child: TextButton(
onPressed: state.isPoweringOff onPressed: state.isPoweringOff
? null ? null
: () => _handlePowerOff(context, cubit), : () => cubit.remotePowerOff(),
child: state.isPoweringOff child: state.isPoweringOff
? SizedBox( ? SizedBox(
width: 32.sp, width: 32.sp,
...@@ -162,38 +173,4 @@ class DeviceDetailView extends StatelessWidget { ...@@ -162,38 +173,4 @@ class DeviceDetailView extends StatelessWidget {
), ),
); );
} }
Future<void> _handlePowerOn(BuildContext context, DeviceCubit cubit) async {
try {
await cubit.remotePowerOn();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('远程送电成功')),
);
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('远程送电失败: $e')),
);
}
}
}
Future<void> _handlePowerOff(BuildContext context, DeviceCubit cubit) async {
try {
await cubit.remotePowerOff();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('远程断电成功')),
);
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('远程断电失败: $e')),
);
}
}
}
} }
\ No newline at end of file
...@@ -22,6 +22,7 @@ class DeviceListItem extends StatelessWidget { ...@@ -22,6 +22,7 @@ class DeviceListItem extends StatelessWidget {
borderRadius: BorderRadius.circular(20.r), borderRadius: BorderRadius.circular(20.r),
), ),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
margin: EdgeInsets.only(bottom: 20.h),
child: Row( child: Row(
children: [ children: [
Container( Container(
......
...@@ -80,14 +80,18 @@ class InspectionDeviceView extends StatelessWidget { ...@@ -80,14 +80,18 @@ class InspectionDeviceView extends StatelessWidget {
lastInspectionTime: state.lastInspectionTime, lastInspectionTime: state.lastInspectionTime,
icon: state.icon, icon: state.icon,
), ),
SizedBox(height: 20.h), if (state.inspectionHistory.isNotEmpty) ...[
InspectionHistoryCard( SizedBox(height: 20.h),
historyList: state.inspectionHistory, InspectionHistoryCard(
), historyList: state.inspectionHistory,
// SizedBox(height: 20.h), ),
InspectionItemsCard( ],
items: state.inspectionItems, if (state.inspectionItems.isNotEmpty) ...[
), SizedBox(height: 20.h),
InspectionItemsCard(
items: state.inspectionItems,
),
],
SizedBox(height: 30.h), SizedBox(height: 30.h),
StartInspectionButton(deviceId: state.deviceId), StartInspectionButton(deviceId: state.deviceId),
SizedBox(height: 20.h), SizedBox(height: 20.h),
......
...@@ -76,14 +76,18 @@ class DeviceOverviewCard extends StatelessWidget { ...@@ -76,14 +76,18 @@ class DeviceOverviewCard extends StatelessWidget {
Container( Container(
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 10.h), padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 10.h),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromRGBO(225, 245, 238, 1.0), color: deviceStatus == '1'
? const Color.fromRGBO(225, 245, 238, 1.0)
: const Color.fromRGBO(255, 235, 238, 1.0),
borderRadius: BorderRadius.circular(20.r), borderRadius: BorderRadius.circular(20.r),
), ),
child: Text( child: Text(
deviceStatus, deviceStatus == '1' ? '在线' : '离线',
style: TextStyle( style: TextStyle(
fontSize: 28.sp, fontSize: 28.sp,
color: const Color.fromRGBO(26, 188, 156, 1.0), color: deviceStatus == '1'
? const Color.fromRGBO(26, 188, 156, 1.0)
: const Color.fromRGBO(231, 76, 60, 1.0),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
......
...@@ -18,6 +18,7 @@ class InspectionRecordItem extends StatelessWidget { ...@@ -18,6 +18,7 @@ class InspectionRecordItem extends StatelessWidget {
borderRadius: BorderRadius.circular(20.r), borderRadius: BorderRadius.circular(20.r),
), ),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
margin: EdgeInsets.only(bottom: 20.h),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
......
...@@ -41,111 +41,104 @@ class InspectionTopologyCubit extends Cubit<InspectionTopologyState> { ...@@ -41,111 +41,104 @@ class InspectionTopologyCubit extends Cubit<InspectionTopologyState> {
final rootNode = _buildTopologyTree(nodes); final rootNode = _buildTopologyTree(nodes);
// 计算连接数: 父节点到每个子节点一条连接
int connectionCount = 0;
for (final child in rootNode.children) {
connectionCount++; // 根到子
connectionCount += child.children.length; // 子到孙
}
emit(InspectionTopologyState( emit(InspectionTopologyState(
deviceName: info.deviceName, deviceName: info.deviceName,
deviceModel: '${info.deviceCode}·${info.locationText}', deviceModel: '${info.deviceCode}·${info.deviceLocation}',
topologyNodes: [rootNode], topologyNodes: [rootNode],
deviceCount: _countAllNodes(rootNode), deviceCount: _countAllNodes(rootNode),
connectionCount: connectionCount, connectionCount: _countConnections(rootNode),
// statusText:
)); ));
} }
/// 将 API 返回的扁平节点列表转换为树结构 + 自动计算位置 /// 根据 gatewayId 将扁平节点列表构建为树结构,并自动计算布局位置
TopologyNode _buildTopologyTree(List<TreeNodeBO> nodes) { TopologyNode _buildTopologyTree(List<TreeNodeBO> nodes) {
if (nodes.isEmpty) { if (nodes.isEmpty) {
return TopologyNode( return const TopologyNode(
id: '0', id: '0',
name: '未知设备', name: '未知设备',
status: 'offline', status: 'offline',
children: [], children: [],
x: 0.5, x: 0.5,
y: 0.15, y: 0.08,
); );
} }
// 第一个节点作为根节点 // 构建子节点映射表:parent deviceId -> [child TreeNodeBO]
final root = nodes.first; final childrenMap = <int, List<TreeNodeBO>>{};
final children = nodes.length > 1 ? nodes.sublist(1) : <TreeNodeBO>[]; final nodeMap = <int, TreeNodeBO>{};
for (final node in nodes) {
// 如果子节点 <= 6,平分到第二层;否则将前6个放第二层,其余作为叶子 nodeMap[node.deviceId] = node;
final int maxLevel2 = 6; final parentId = node.gatewayId ?? 0;
final level2Nodes = children.take(maxLevel2).toList(); childrenMap.putIfAbsent(parentId, () => []).add(node);
final leafNodes = children.length > maxLevel2 }
? children.sublist(maxLevel2)
: <TreeNodeBO>[]; // 查找根节点:gatewayId 为 null/0,或引用的父节点不存在于列表中
final nodeIds = nodeMap.keys.toSet();
final rootNode = TopologyNode( final roots = nodes.where((n) =>
id: root.deviceId.toString(), n.gatewayId == null ||
name: root.deviceName, n.gatewayId == 0 ||
status: root.status, !nodeIds.contains(n.gatewayId),
x: 0.5, ).toList();
y: 0.15,
children: level2Nodes.asMap().entries.map((entry) { if (roots.isEmpty) {
final idx = entry.key; // fallback:取第一个节点作为根
final node = entry.value; roots.add(nodes.first);
// 在第二层均匀分布 }
final xPos = (level2Nodes.length == 1)
? 0.5 // 递归构建节点并计算布局位置
: 0.15 + (0.7 * idx / (level2Nodes.length - 1)); TopologyNode buildNode(TreeNodeBO node, int depth, double xCenter, double xSpan) {
return TopologyNode( final children = childrenMap[node.deviceId] ?? [];
id: node.deviceId.toString(), final childNodes = <TopologyNode>[];
name: node.deviceName,
status: node.status, if (children.isNotEmpty) {
x: xPos, for (int i = 0; i < children.length; i++) {
y: 0.45, final childX = children.length == 1
children: [], ? xCenter
); : xCenter - xSpan / 2 + (xSpan * i / (children.length - 1));
}).toList(), childNodes.add(buildNode(children[i], depth + 1, childX, xSpan * 0.55));
); }
}
// 补充叶子节点:附着到最近的第二层节点上
if (leafNodes.isNotEmpty && rootNode.children.isNotEmpty) { return TopologyNode(
final leafNode = leafNodes.first; id: node.deviceId.toString(),
final lastLevel2Idx = rootNode.children.length - 1; name: node.deviceName,
final lastLevel2 = rootNode.children[lastLevel2Idx]; status: node.status,
final updatedChildren = List<TopologyNode>.from(rootNode.children); statusText: node.statusText,
updatedChildren[lastLevel2Idx] = TopologyNode( gatewayId: node.gatewayId?.toString(),
id: lastLevel2.id, x: xCenter.clamp(0.05, 0.95),
name: lastLevel2.name, y: (0.08 + depth * 0.17).clamp(0.02, 0.98),
status: lastLevel2.status, children: childNodes,
x: lastLevel2.x,
y: lastLevel2.y,
children: leafNodes.asMap().entries.map((entry) {
final idx = entry.key;
final leaf = entry.value;
final xPos = (leafNodes.length == 1)
? lastLevel2.x
: lastLevel2.x -
0.1 +
(0.2 * idx / (leafNodes.length - 1));
return TopologyNode(
id: leaf.deviceId.toString(),
name: leaf.deviceName,
status: leaf.status,
x: xPos,
y: 0.75,
children: [],
);
}).toList(),
); );
}
if (roots.length == 1) {
return buildNode(roots.first, 0, 0.5, 0.7);
} else {
// 多个根节点:创建一个虚拟根,将所有根均匀分布在第二层
final virtualChildren = <TopologyNode>[];
for (int i = 0; i < roots.length; i++) {
final xPos = 0.1 + (0.8 * i / (roots.length - 1));
virtualChildren.add(buildNode(roots[i], 1, xPos, 0.35));
}
return TopologyNode( return TopologyNode(
id: rootNode.id, id: '0',
name: rootNode.name, name: '根节点',
status: rootNode.status, status: 'online',
x: rootNode.x, x: 0.5,
y: rootNode.y, y: 0.08,
children: updatedChildren, children: virtualChildren,
); );
} }
}
return rootNode; /// 递归计算连接数
int _countConnections(TopologyNode node) {
int count = 0;
for (final child in node.children) {
count += 1 + _countConnections(child);
}
return count;
} }
int _countAllNodes(TopologyNode node) { int _countAllNodes(TopologyNode node) {
......
...@@ -10,6 +10,7 @@ class InspectionTopologyState extends Equatable { ...@@ -10,6 +10,7 @@ class InspectionTopologyState extends Equatable {
final int deviceCount; final int deviceCount;
final int connectionCount; final int connectionCount;
final TopologyNode? selectedNode; final TopologyNode? selectedNode;
final String statusText;
const InspectionTopologyState({ const InspectionTopologyState({
this.isLoading = false, this.isLoading = false,
...@@ -20,6 +21,7 @@ class InspectionTopologyState extends Equatable { ...@@ -20,6 +21,7 @@ class InspectionTopologyState extends Equatable {
this.deviceCount = 0, this.deviceCount = 0,
this.connectionCount = 0, this.connectionCount = 0,
this.selectedNode, this.selectedNode,
this.statusText = ''
}); });
InspectionTopologyState copyWith({ InspectionTopologyState copyWith({
...@@ -31,6 +33,7 @@ class InspectionTopologyState extends Equatable { ...@@ -31,6 +33,7 @@ class InspectionTopologyState extends Equatable {
int? deviceCount, int? deviceCount,
int? connectionCount, int? connectionCount,
TopologyNode? selectedNode, TopologyNode? selectedNode,
String? statusText,
}) { }) {
return InspectionTopologyState( return InspectionTopologyState(
isLoading: isLoading ?? this.isLoading, isLoading: isLoading ?? this.isLoading,
...@@ -41,6 +44,7 @@ class InspectionTopologyState extends Equatable { ...@@ -41,6 +44,7 @@ class InspectionTopologyState extends Equatable {
deviceCount: deviceCount ?? this.deviceCount, deviceCount: deviceCount ?? this.deviceCount,
connectionCount: connectionCount ?? this.connectionCount, connectionCount: connectionCount ?? this.connectionCount,
selectedNode: selectedNode, selectedNode: selectedNode,
statusText: statusText ?? this.statusText,
); );
} }
...@@ -54,6 +58,7 @@ class InspectionTopologyState extends Equatable { ...@@ -54,6 +58,7 @@ class InspectionTopologyState extends Equatable {
deviceCount, deviceCount,
connectionCount, connectionCount,
selectedNode, selectedNode,
statusText
]; ];
} }
...@@ -64,6 +69,8 @@ class TopologyNode extends Equatable { ...@@ -64,6 +69,8 @@ class TopologyNode extends Equatable {
final List<TopologyNode> children; final List<TopologyNode> children;
final double x; final double x;
final double y; final double y;
final String? gatewayId;
final String? statusText;
const TopologyNode({ const TopologyNode({
required this.id, required this.id,
...@@ -72,8 +79,10 @@ class TopologyNode extends Equatable { ...@@ -72,8 +79,10 @@ class TopologyNode extends Equatable {
required this.children, required this.children,
required this.x, required this.x,
required this.y, required this.y,
this.gatewayId,
this.statusText,
}); });
@override @override
List<Object?> get props => [id, name, status, children, x, y]; List<Object?> get props => [id, name, status, children, x, y, gatewayId, statusText];
} }
\ No newline at end of file
...@@ -118,6 +118,7 @@ class InspectionTopologyPage extends StatelessWidget { ...@@ -118,6 +118,7 @@ class InspectionTopologyPage extends StatelessWidget {
if (state.selectedNode != null) if (state.selectedNode != null)
DeviceDetailDialog( DeviceDetailDialog(
node: state.selectedNode!, node: state.selectedNode!,
curentState: state,
onClose: () => onClose: () =>
context.read<InspectionTopologyCubit>().selectNode(null), context.read<InspectionTopologyCubit>().selectNode(null),
), ),
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
import '../cubit/inspection_topology_state.dart'; import '../cubit/inspection_topology_state.dart';
class DeviceDetailDialog extends StatelessWidget { class DeviceDetailDialog extends StatelessWidget {
final TopologyNode node; final TopologyNode node;
final InspectionTopologyState curentState;
final VoidCallback onClose; final VoidCallback onClose;
const DeviceDetailDialog({ const DeviceDetailDialog({
super.key, super.key,
required this.node, required this.node,
required this.curentState,
required this.onClose, required this.onClose,
}); });
...@@ -87,7 +91,7 @@ class DeviceDetailDialog extends StatelessWidget { ...@@ -87,7 +91,7 @@ class DeviceDetailDialog extends StatelessWidget {
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
Text( Text(
'传感器', curentState.deviceModel,
style: TextStyle( style: TextStyle(
fontSize: 24.sp, fontSize: 24.sp,
color: const Color.fromRGBO(148, 163, 184, 1), color: const Color.fromRGBO(148, 163, 184, 1),
...@@ -106,7 +110,7 @@ class DeviceDetailDialog extends StatelessWidget { ...@@ -106,7 +110,7 @@ class DeviceDetailDialog extends StatelessWidget {
borderRadius: BorderRadius.circular(40.r), borderRadius: BorderRadius.circular(40.r),
), ),
child: Text( child: Text(
'正常', node.statusText?? '-',
style: TextStyle( style: TextStyle(
fontSize: 24.sp, fontSize: 24.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
...@@ -141,7 +145,7 @@ class DeviceDetailDialog extends StatelessWidget { ...@@ -141,7 +145,7 @@ class DeviceDetailDialog extends StatelessWidget {
), ),
), ),
Text( Text(
'dev-${node.id.padLeft(3, '0')}', '${node.id}',
style: TextStyle( style: TextStyle(
fontSize: 24.sp, fontSize: 24.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
...@@ -179,7 +183,14 @@ class DeviceDetailDialog extends StatelessWidget { ...@@ -179,7 +183,14 @@ class DeviceDetailDialog extends StatelessWidget {
width: double.infinity, width: double.infinity,
height: 104.h, height: 104.h,
child: ElevatedButton( child: ElevatedButton(
onPressed: () {}, onPressed: () {
final deviceId = int.tryParse(node.id) ?? 0;
if (deviceId > 0) {
context.pushRoute(
DeviceDetailRoute(deviceId: deviceId),
);
}
},
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromRGBO(59, 130, 246, 1), backgroundColor: const Color.fromRGBO(59, 130, 246, 1),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
......
# 智慧酒店 App 接口对接方案 # 智慧酒店 App 接口对接方案
...@@ -1153,6 +1153,7 @@ class xxxBO extends Equatable { ...@@ -1153,6 +1153,7 @@ class xxxBO extends Equatable {
{ {
"deviceId": 0, "deviceId": 0,
"deviceName": "string", "deviceName": "string",
"gatewayId":0, // 父级id
"deviceType": "string", "deviceType": "string",
"icon": "string", "icon": "string",
"status": "string", "status": "string",
......
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