Files
tuiche/lib/pages/device/component/DeviceDataComponentWidget.dart
2025-11-17 10:07:07 +08:00

1485 lines
60 KiB
Dart

import 'dart:async';
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/ToggleColorContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/enum/BindType.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class DeviceDataComponentWidget extends StatefulWidget {
final Map<String, dynamic> device;
const DeviceDataComponentWidget({super.key, required this.device});
@override
State<DeviceDataComponentWidget> createState() =>
_DeviceDataComponentWidgetState();
}
class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
final GlobalKey _arrowKey = GlobalKey();
OverlayEntry? _popupEntry;
BodyDeviceController bodyDeviceController = Get.find();
PersonController personController = Get.find();
bool _isPopupOpen = false;
var lisObj;
@override
void dispose() {
_popupEntry?.remove();
super.dispose();
}
@override
void initState() {
super.initState();
}
void _showPopup() {
setState(() {
_isPopupOpen = true;
});
final RenderBox? renderBox =
_arrowKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox == null) return;
final position = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
final screenSize = MediaQuery.of(context).size;
final screenHeight = screenSize.height;
final screenWidth = screenSize.width;
// final popupWidth = 190.rpx;
var popupWidth = 190.rpx;
final paddingOffset = 10.rpx;
// 构建弹窗内容
final popupContent = _buildPopupContent();
final textStyle = TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
);
final allTexts = [
"体征检测设备.首页展示".tr,
"体征检测设备.设备详情".tr,
"WIFI配置".tr,
"设备校准".tr,
"分享设备".tr,
"消息设置".tr,
"体征检测设备.重命名".tr,
"体征检测设备.删除".tr,
];
final menuWidth = _calculateMaxMenuItemWidth(allTexts, textStyle);
popupWidth = menuWidth;
// 计算弹窗需要的实际高度(估算)
final estimatedItemHeight = 66.rpx; // 每个菜单项的估算高度
//todo 更新菜单项,需要在此添加数量
final itemCount =
widget.device['bind_type'] == BindType.active.code ? 9 : 5;
final estimatedPopupHeight =
(itemCount * estimatedItemHeight) + 40.rpx; // 加上padding
// 计算可用空间
final availableSpaceBelow =
screenHeight - position.dy - size.height - paddingOffset;
final availableSpaceAbove = position.dy - paddingOffset;
// 决定显示位置和实际高度
bool showAbove;
double popupTop;
double actualPopupHeight;
if (availableSpaceBelow >= estimatedPopupHeight ||
(availableSpaceBelow < estimatedPopupHeight &&
availableSpaceAbove > availableSpaceBelow)) {
// 显示在下方的条件:下方空间足够,或者下方空间比上方大
showAbove = false;
popupTop = position.dy + size.height + paddingOffset;
actualPopupHeight = math.min(estimatedPopupHeight, availableSpaceBelow);
} else {
// 显示在上方
showAbove = true;
actualPopupHeight = math.min(estimatedPopupHeight, availableSpaceAbove);
popupTop = position.dy - actualPopupHeight - paddingOffset;
}
// 确保弹窗不会超出屏幕边界
popupTop = math.max(paddingOffset, popupTop);
actualPopupHeight =
math.min(actualPopupHeight, screenHeight * 0.7); // 限制最大高度为屏幕的70%
// 计算左侧位置,确保不会超出屏幕右侧
double popupLeft = position.dx + size.width - popupWidth;
if (popupLeft + popupWidth > screenWidth) {
popupLeft = screenWidth - popupWidth - paddingOffset;
}
// setState(() {
// _isPopupOpen = false;
// });
_popupEntry?.remove();
_popupEntry = OverlayEntry(
builder: (context) => GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
},
child: Stack(
children: [
Positioned(
top: popupTop,
left: popupLeft,
child: Material(
color: Colors.transparent,
child: Container(
constraints: BoxConstraints(
// maxWidth: popupWidth,
maxWidth: screenWidth,
maxHeight: actualPopupHeight,
),
decoration: BoxDecoration(
color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(12.rpx),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 12.rpx,
spreadRadius: 1.rpx,
offset: Offset(0, 6.rpx),
),
],
),
child: SingleChildScrollView(
child: popupContent,
),
),
),
),
],
),
),
);
Overlay.of(context)?.insert(_popupEntry!);
}
// 构建弹窗内容
Widget _buildPopupContent() {
final content = Container(
padding: EdgeInsets.all(20.rpx),
// decoration: BoxDecoration(
// color: themeController.currentColor.sc17,
// borderRadius: BorderRadius.circular(12.rpx),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.2),
// blurRadius: 12.rpx,
// spreadRadius: 1.rpx,
// offset: Offset(0, 6.rpx),
// ),
// ],
// ),
child: Column(
mainAxisSize: MainAxisSize.min,
children: _buildMenuItems().divide(SizedBox(
height: 6.rpx,
)),
),
);
return widget.device['bind_type'] == BindType.active.code
? _buildActiveDeviceContent(content)
: _buildSharedDeviceContent(content);
}
// 构建主动绑定设备的菜单项
Widget _buildActiveDeviceContent(Widget content) {
return IntrinsicWidth(
child: content,
);
}
// 构建共享设备的菜单项
Widget _buildSharedDeviceContent(Widget content) {
return IntrinsicWidth(
child: content,
);
}
// 构建菜单项列表
List<Widget> _buildMenuItems() {
final items = <Widget>[
_buildMenuItem(
icon: widget.device['show'] != null && widget.device['show'] == true
? Icon(Icons.check,
size: 24.rpx, color: themeController.currentColor.sc2)
: null,
text: "体征检测设备.首页展示".tr,
onTap: () async {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
ApiResponse apiResponse =
await bodyDeviceController.updateDeviceShow(widget.device);
if (apiResponse.code == HttpStatusCodes.ok) {
bodyDeviceController.getDeviceList();
bodyDeviceController.updateAll();
} else {
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
},
textColor:
(widget.device['show'] != null && widget.device['show'] == true)
? themeController.currentColor.sc2
: themeController.currentColor.sc3,
),
_buildMenuItem(
text: "体征检测设备.设备详情".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
Get.toNamed("/deviceDetail", arguments: widget.device);
},
),
];
if (widget.device['bind_type'] == BindType.active.code &&
!AppConstants.is_test_account) {
items.addAll([
_buildMenuItem(
text: "WIFI配置".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
dealWifi(widget.device);
},
),
_buildMenuItem(
text: "设备校准".tr,
onTap: () async {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
BlueteethBindController blueteethBindController = Get.find();
blueteethBindController.currentDeviceMac?.value =
widget.device['mac'];
await Get.toNamed("/calibrationPersonPage", arguments: 2);
},
),
_buildMenuItem(
text: "分享设备".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
Get.toNamed("/deviceSharePage", arguments: widget.device);
},
),
_buildMenuItem(
text: "消息设置".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
// Get.toNamed("/deviceDetail", arguments: widget.device);
Get.toNamed("/messageSettingPage", arguments: widget.device);
// TopSlideNotification.show(context, text: "待开发功能".tr);
},
),
]);
}
items.addAll([
_buildMenuItem(
text: "体征检测设备.重命名".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
_showRenameDialog();
},
),
_buildMenuItem(
text: widget.device['bind_type'] == BindType.active.code
? "解绑".tr
: "删除".tr,
onTap: () {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
_showUnbindConfirmDialog();
},
),
]);
return items;
}
// 构建单个菜单项
Widget _buildMenuItem({
Widget? icon,
required String text,
required VoidCallback onTap,
Color? textColor,
}) {
return ClickableContainer(
padding: EdgeInsets.symmetric(vertical: 16.rpx),
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc16.withOpacity(0.1),
borderRadius: 8.rpx,
onTap: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
icon ?? SizedBox(width: 24.rpx, height: 24.rpx),
SizedBox(width: 10.rpx),
Expanded(
child: Text(
text,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: textColor ?? themeController.currentColor.sc3,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
// 显示重命名对话框
void _showRenameDialog() {
personController.currentPersonId.value = widget.device['_id'];
personController.name.value = "";
String text = "确定".tr;
showSingleConfirmDialog(
context,
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 41.rpx, 0.rpx, 0),
child: Container(
height: 80.rpx,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.rpx),
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: TextFormField(
onChanged: (value) {
if (value == null || value.isEmpty) {
personController.name.value = "体征监测设备".tr;
} else {
personController.name.value = value;
}
},
autofocus: false,
decoration: InputDecoration(
isDense: true,
// hintText: '请输入人员名称'.tr,
hintText: "体征监测设备".tr,
hintStyle: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
),
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: Colors.black,
),
cursorColor: Colors.white,
initialValue: widget.device['person']['name'] == null ||
widget.device['person']['name'] == ""
? "体征监测设备".tr
: widget.device['person']['name'],
),
),
),
),
'修改人员名称'.tr,
onConfirm: () async {
ApiResponse response = await personController.updatePersonName(
widget.device['person'],
widget.device['_id'],
);
if (response.code == HttpStatusCodes.ok) {
await bodyDeviceController.getDeviceList();
bodyDeviceController.updateAll();
} else {
TopSlideNotification.show(
context,
text: response.msg!,
textColor: themeController.currentColor.sc9,
);
}
},
onCancel: () {
print('用户点击了取消');
},
confirmText: text,
);
}
// 显示解绑确认对话框
void _showUnbindConfirmDialog() {
showConfirmDialog(
context,
Container(),
"是否确认解绑".tr,
onConfirm: () async {
ApiResponse apiResponse =
await bodyDeviceController.deleteDevice(widget.device);
if (apiResponse.code == HttpStatusCodes.ok) {
bodyDeviceController.getDeviceList();
TopSlideNotification.show(
context,
text: apiResponse.msg!,
);
} else {
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
},
onCancel: () {},
);
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
constraints: BoxConstraints(
// maxWidth: MediaQuery.sizeOf(context).width - 200.rpx,
maxWidth: MediaQuery.sizeOf(context).width * 0.6,
),
child: Text(
'${widget.device['person']?['name'] ?? '未命名'.tr}',
style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
// ClickableContainer(
// key: _arrowKey,
// padding: EdgeInsetsDirectional.fromSTEB(
// 16.rpx, 16.rpx, 14.rpx, 16.rpx),
// backgroundColor: Colors.transparent,
// highlightColor: Colors.black.withOpacity(0.1),
// borderRadius: 8.rpx,
// onTap: _showPopup,
// child: Container(
// width: 15.rpx,
// height: 8.rpx,
// child: SvgPicture.asset(
// 'assets/img/icon/arrow_down.svg',
// fit: BoxFit.cover,
// color: Colors.white,
// ),
// ),
// ),
ToggleColorContainer(
key: _arrowKey,
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx,
16.rpx,
14.rpx,
16.rpx,
),
initialColor: Colors.transparent,
toggledColor: Colors.black.withOpacity(0.5),
borderRadius: 8.rpx,
onToggle: _showPopup,
toggled: _isPopupOpen,
child: Container(
width: 15.rpx,
height: 8.rpx,
child: SvgPicture.asset(
'assets/img/icon/arrow_down.svg',
fit: BoxFit.cover,
color: Colors.white,
),
),
),
],
),
SizedBox(height: 40.rpx),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 100.rpx,
constraints: BoxConstraints(
minWidth: 105.rpx,
),
decoration: BoxDecoration(),
child: Text(
'设备ID'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
Text(
'${widget.device['code'] ?? '未知数据'.tr}',
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 34.rpx)),
),
SizedBox(height: 40.rpx),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 100.rpx,
constraints: BoxConstraints(
minWidth: 105.rpx,
),
decoration: BoxDecoration(),
child: Text(
'更新时间'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
Text(
'${widget.device['status']['updateTime'] != null ? MyUtils.timestampToDateString(widget.device['status']['updateTime']) : '未知时间'.tr}',
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 34.rpx)),
),
SizedBox(height: 40.rpx),
if (widget.device['bind_type'] == BindType.active.code)
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 100.rpx,
constraints: BoxConstraints(
minWidth: 105.rpx,
),
decoration: BoxDecoration(),
child: Text(
'已分享'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
Text(
'${widget.device['shareNum']}' + "".tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 34.rpx)),
),
// Icon(
// Icons.arrow_back,
// color: FlutterFlowTheme.of(context).primaryText,
// size: 24.rpx,
// ),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 14.rpx, 0),
// child: Container(
// width: 28.rpx,
// height: 28.rpx,
// // width: double.infinity,
// decoration: BoxDecoration(),
// child: SvgPicture.asset(
// 'assets/img/icon/group.svg',
// fit: BoxFit.cover,
// // color: stringToColor("#333333"), //固定
// color: Colors.white,
// ),
// ),
// ),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white, // 或设置为你需要的水波纹颜色
padding: EdgeInsetsDirectional.fromSTEB(
14.rpx, 0.rpx, 14.rpx, 0), //
borderRadius: 0.rpx, // 圆形点击区域
onTap: () {
// 你的点击逻辑
Get.toNamed("/deviceShareListPage",
arguments: widget.device['mac']);
},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0), // 外部 padding 移到内部
width: 28.rpx,
height: 24.rpx,
child: SvgPicture.asset(
'assets/img/icon/group.svg',
fit: BoxFit.fill,
color: Colors.white,
),
),
)
].divide(SizedBox(width: 34.rpx)),
),
if (widget.device['bind_type'] == BindType.share.code)
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 100.rpx,
constraints: BoxConstraints(
minWidth: 105.rpx,
),
decoration: BoxDecoration(),
child: Text(
'设备来源'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
Text(
(widget.device['source']?.toString().isEmpty ?? true)
? '未知数据'.tr
: widget.device['source'].toString(),
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 34.rpx)),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 14.rpx, 0),
child: Container(
decoration: BoxDecoration(),
child: Text(
"云关爱".tr,
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
),
),
),
].divide(SizedBox(width: 34.rpx)),
),
SizedBox(height: 40.rpx),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 100.rpx,
constraints: BoxConstraints(
minWidth: 105.rpx,
),
decoration: BoxDecoration(),
child: Text(
'体征检测设备.设备状态'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
if (widget.device['status']['signal'] != null &&
widget.device['status']['signal'] != -1 &&
widget.device['status']['status'] != null &&
widget.device['status']['status'] == 1)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey, // 或根据你主题定制颜色
padding: EdgeInsets.zero,
borderRadius: 0,
onTap: () {
// 点击事件
showTipDialog(
context,
Container(
child: RichText(
text: TextSpan(
text: "信号强度".tr, // 文本前缀部分
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().title_text_fontSize,
),
children: [
TextSpan(
text: getBedSignal(
widget.device['status']
['signal']), // 状态部分
style: TextStyle(
color: themeController.currentColor
.sc2, // 同样颜色,也可改成其他颜色
fontSize: AppConstants()
.title_text_fontSize,
),
),
],
),
),
),
);
},
child: Container(
width: 30.rpx,
height: 24.rpx,
child: Image.asset(
'assets/img/signal${_getSignalLevel(widget.device['status']['signal'])}.png'),
),
),
if (widget.device['status']['inBed'] != null &&
widget.device['status']['status'] != null &&
widget.device['status']['status'] == 1)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey,
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
borderRadius: 0,
onTap: () {
showTipDialog(
context,
Container(
child: RichText(
text: TextSpan(
text: "是否在床".tr, // 文本前缀部分
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().title_text_fontSize,
),
children: [
TextSpan(
text: getBedStatus(widget
.device['status']['inBed']), // 状态部分
style: TextStyle(
color: themeController.currentColor
.sc2, // 同样颜色,也可改成其他颜色
fontSize: AppConstants()
.title_text_fontSize,
),
),
],
),
),
),
);
},
child: SizedBox(
width: 16.rpx,
height: 36.rpx,
child: SvgPicture.asset(
widget.device['status']['inBed'] == 0
? 'assets/img/icon/not_bed.svg'
: 'assets/img/icon/in_bed.svg',
fit: BoxFit.fill,
),
),
),
if (widget.device['status']['failure'] != 0 &&
widget.device['status']['status'] != null &&
widget.device['status']['status'] == 1)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey, // 可自定义点击水波纹颜色
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
borderRadius: 0,
onTap: () {
showTipDialog(
context,
Container(
child: RichText(
text: TextSpan(
text: "设备故障".tr, // 文本前缀部分
style: TextStyle(
color: themeController.currentColor.sc9,
fontSize:
AppConstants().title_text_fontSize,
),
children: [
// TextSpan(
// text:widget
// .device['status']['status'] == 1?"在线".tr:"离线".tr, // 状态部分
// style: TextStyle(
// color: themeController.currentColor
// .sc2, // 同样颜色,也可改成其他颜色
// fontSize: AppConstants()
// .title_text_fontSize,
// ),
// ),
],
),
),
),
);
},
child: SizedBox(
width: 27.rpx,
height: 27.rpx,
child: SvgPicture.asset(
'assets/img/icon/device_issue.svg',
fit: BoxFit.cover,
),
),
),
if (widget.device['status']['upgrade'] != 0 &&
widget.device['status']['status'] != null &&
widget.device['status']['status'] == 1)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey, // 可自定义点击效果颜色
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
borderRadius: 0,
onTap: () {
//todo 升级
},
child: SizedBox(
width: 34.rpx,
height: 24.rpx,
child: SvgPicture.asset(
'assets/img/icon/upgrade.svg',
fit: BoxFit.cover,
// color: themeController.currentColor.sc3, // 若你想加颜色控制可取消注释
),
),
),
if (widget.device['status']['status'] != null &&
widget.device['status']['status'] == 0)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey, // 可替换为点击高亮色
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
borderRadius: 0,
onTap: () {
showTipDialog(
context,
Container(
child: RichText(
text: TextSpan(
text: "网络状态".tr, // 文本前缀部分
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().title_text_fontSize,
),
children: [
TextSpan(
text: widget.device['status']
['status'] ==
1
? "在线".tr
: "离线".tr, // 状态部分
style: TextStyle(
color: themeController.currentColor
.sc2, // 同样颜色,也可改成其他颜色
fontSize: AppConstants()
.title_text_fontSize,
),
),
],
),
),
),
);
},
child: SizedBox(
width: 27.rpx,
height: 27.rpx,
child: SvgPicture.asset(
// widget.device['status']['status'] == 1
// ? 'assets/img/icon/device_online.svg'
// : 'assets/img/icon/device_offline.svg',
'assets/img/icon/device_issue.svg',
fit: BoxFit.cover,
),
),
),
].divide(SizedBox(width: 50.rpx)),
),
].divide(SizedBox(width: 34.rpx)),
),
SizedBox(height: 20.rpx),
Divider(
thickness: 0.5,
color: themeController.currentColor.sc4,
),
SizedBox(height: 5.rpx),
if (!AppConstants.is_test_account)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () async {
if (widget.device['person'] != null) {
personController.currentPersonId.value =
widget.device['_id'];
personController.name.value =
widget.device['person']['name'];
personController.update_person_mac.value =
widget.device['mac'];
personController.gender.value =
widget.device['person']['gender'] ?? 1;
personController.weight?.value =
widget.device['person']['weight'] == null
? ''
: widget.device['person']['weight']
.toString();
personController.height.value =
widget.device['person']['height'] == null
? ''
: widget.device['person']['height']
.toString();
personController.selectedDiseaseIds.value =
widget.device['person']['disease'] ?? [];
personController.birthday.value =
widget.device['person']['birthday'] ?? '';
personController.dateTime =
MyUtils.formatBirthdayTime(
widget.device['person']['birthday']);
} else {
personController.update_person_mac.value =
widget.device['mac'];
personController.currentPersonId.value =
widget.device['_id'];
personController.name.value = "";
personController.gender.value = 1;
personController.dateTime = null;
personController.height.value = "";
personController.weight.value = "";
personController.diseaseList.value = [];
}
await Get.toNamed("/updatePersonPage",
arguments: widget.device['bind_type']);
bodyDeviceController.getDeviceList();
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Container(
alignment: Alignment.center,
height: MediaQuery.sizeOf(context).height * 0.0037,
constraints: BoxConstraints(
minWidth: 143.rpx,
minHeight: 61.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"体征检测设备.人员资料".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
),
SizedBox(
width: 20.rpx,
),
Expanded(
// 使用 Expanded 来占据屏幕宽度
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
Get.toNamed("/instantBodyPage",
arguments: widget.device);
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
alignment: Alignment.center,
height: MediaQuery.sizeOf(context).height * 0.0037,
constraints: BoxConstraints(
minWidth: 143.rpx,
minHeight: 61.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"体征检测设备.实时体征".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize: AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
],
),
if (!AppConstants.is_test_account)
SizedBox(
height: 20.rpx,
),
if (!AppConstants.is_test_account)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
// 使用 Expanded 来占据屏幕宽度的一半
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
// TopSlideNotification.show(context, text: "待开发功能".tr);
Get.toNamed("/messageReviewPage",
arguments: widget.device);
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Container(
alignment: Alignment.center,
height: MediaQuery.sizeOf(context).height * 0.0037,
constraints: BoxConstraints(
minWidth: 143.rpx,
minHeight: 61.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"体征检测设备.消息回看".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
),
SizedBox(
width: 20.rpx,
),
Expanded(
// 使用 Expanded 来占据屏幕宽度的一半
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
// String mac = widget.device['mac'];
// String sleepReportUrl =
// "${ServiceConstant.sleep_report_url}?mac=${mac}&token=${ServiceConstant.sleep_token}";
// Get.toNamed("/sleepReportPage",
// arguments: sleepReportUrl);
Get.toNamed("/newSleepReportPage", arguments: {
'date': DateTime.now().millisecondsSinceEpoch,
"mac": widget.device['mac'],
'type': 1,
'name': 'sleep', //'sleep', 'heartRate' 或 'breathe'
// 'itemName': widget.data['id'],
'person': widget.device['person'],
});
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Container(
alignment: Alignment.center,
height: MediaQuery.sizeOf(context).height * 0.0037,
constraints: BoxConstraints(
minWidth: 143.rpx,
minHeight: 61.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"体征检测设备.睡眠报告".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
),
],
),
if (AppConstants.is_test_account)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
// Expanded(
// child: CustomCard(
// borderRadius: AppConstants().button_container_radius,
// onTap: () async {
// if (widget.device['person'] != null) {
// personController.currentPersonId.value =
// widget.device['_id'];
// personController.name.value =
// widget.device['person']['name'];
// personController.update_person_mac.value =
// widget.device['mac'];
// personController.gender.value =
// widget.device['person']['gender'] ?? 1;
// personController.weight?.value =
// widget.device['person']['weight'] == null
// ? ''
// : widget.device['person']['weight']
// .toString();
// personController.height.value =
// widget.device['person']['height'] == null
// ? ''
// : widget.device['person']['height']
// .toString();
// personController.selectedDiseaseIds.value =
// widget.device['person']['disease'] ?? [];
// personController.birthday.value =
// widget.device['person']['birthday'] ?? '';
// personController.dateTime =
// MyUtils.formatBirthdayTime(
// widget.device['person']['birthday']);
// } else {
// personController.update_person_mac.value =
// widget.device['mac'];
// personController.currentPersonId.value =
// widget.device['_id'];
// personController.name.value = "";
// personController.gender.value = 1;
// personController.dateTime = null;
// personController.height.value = "";
// personController.weight.value = "";
// personController.diseaseList.value = [];
// }
// await Get.toNamed("/updatePersonPage",
// arguments: widget.device['bind_type']);
// bodyDeviceController.getDeviceList();
// },
// colors: [
// themeController.currentColor.sc1,
// themeController.currentColor.sc2,
// ],
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 0.rpx, 0.rpx, 0.rpx),
// child: Container(
// alignment: Alignment.center,
// height: MediaQuery.sizeOf(context).height * 0.0037,
// constraints: BoxConstraints(
// minWidth: 143.rpx,
// minHeight: 61.rpx,
// ),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Text(
// "体征检测设备.人员资料".tr,
// style: TextStyle(
// color: themeController.currentColor.sc3,
// fontFamily: 'Inter',
// fontSize:
// AppConstants().normal_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 17.rpx)),
// ),
// ),
// ),
// ),
// ),
// SizedBox(
// width: 20.rpx,
// ),
Expanded(
// 使用 Expanded 来占据屏幕宽度的一半
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
// TopSlideNotification.show(context, text: "待开发功能".tr);
Get.toNamed("/messageReviewPage",
arguments: widget.device);
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Container(
alignment: Alignment.center,
height: MediaQuery.sizeOf(context).height * 0.0037,
constraints: BoxConstraints(
minWidth: 143.rpx,
minHeight: 61.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"体征检测设备.消息回看".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
),
],
),
].divide(SizedBox(height: 0.rpx)),
),
),
),
);
}
String getBedStatus(int status) {
if (status == 0) {
return "离床".tr;
} else if (status == 1) {
return "在床".tr;
}
return "";
}
getBedSignal(signal) {
if (signal <= 1) {
return "较弱".tr;
}
if (signal > 1 && signal <= 2) {
return "".tr;
}
if (signal > 2 && signal <= 3) {
return "一般".tr;
}
if (signal > 3) {
return "".tr;
}
return "未知数据".tr;
}
Future<void> dealWifi(device) async {
bodyDeviceController.wifiMac = device['mac'];
Get.toNamed("/wifiPagePerson", arguments: device);
return;
}
double _calculateMaxMenuItemWidth(List<String> texts, TextStyle style) {
double maxTextWidth = 0;
for (final text in texts) {
final painter = TextPainter(
text: TextSpan(text: text, style: style),
maxLines: 1,
textDirection: ui.TextDirection.ltr,
)..layout();
if (painter.width > maxTextWidth) {
maxTextWidth = painter.width;
}
}
final iconWidth = 24.rpx;
final spacing = 10.rpx;
final horizontalPadding = 40.rpx;
return iconWidth + spacing + maxTextWidth + horizontalPadding;
}
int _getSignalLevel(int signal) {
if (signal <= 25) {
return 1;
} else if (signal <= 50) {
return 2;
} else if (signal <= 75) {
return 3;
} else {
return 4;
}
}
}