diff --git a/assets/images/mine_avatar.png b/assets/images/mine_avatar.png new file mode 100644 index 0000000..10c981f Binary files /dev/null and b/assets/images/mine_avatar.png differ diff --git a/assets/img/icon/arrow_left.svg b/assets/img/icon/arrow_left.svg index 0e389d4..6767c9c 100644 --- a/assets/img/icon/arrow_left.svg +++ b/assets/img/icon/arrow_left.svg @@ -1 +1 @@ -资源 261 \ No newline at end of file + \ No newline at end of file diff --git a/assets/img/icon/arrow_right.svg b/assets/img/icon/arrow_right.svg index a8d771e..2fa5397 100644 --- a/assets/img/icon/arrow_right.svg +++ b/assets/img/icon/arrow_right.svg @@ -1 +1 @@ -资源 274 \ No newline at end of file + \ No newline at end of file diff --git a/assets/img/icon/xiaoyi.svg b/assets/img/icon/xiaoyi.svg index 4946e11..b4c5fba 100644 --- a/assets/img/icon/xiaoyi.svg +++ b/assets/img/icon/xiaoyi.svg @@ -1 +1 @@ - + diff --git a/lib/component/NullDataComponentWidget.dart b/lib/component/NullDataComponentWidget.dart index 693ab11..fc11cd2 100644 --- a/lib/component/NullDataComponentWidget.dart +++ b/lib/component/NullDataComponentWidget.dart @@ -26,7 +26,7 @@ class _TestWidgetState extends State { height: MediaQuery.sizeOf(context).height * 1, child: Column( mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0), diff --git a/lib/pages/mh_page/MhMessageList.dart b/lib/pages/mh_page/MhMessageList.dart index 6afc202..696599d 100644 --- a/lib/pages/mh_page/MhMessageList.dart +++ b/lib/pages/mh_page/MhMessageList.dart @@ -39,7 +39,7 @@ class _MhMessageListWidgetState extends State { highlightColor: Color(0xFF055466), borderRadius: 20.rpx, padding: - EdgeInsetsDirectional.fromSTEB(31.rpx, 33.rpx, 26.rpx, 26.rpx), + EdgeInsetsDirectional.fromSTEB(30.rpx, 26.rpx, 30.rpx, 26.rpx), onTap: () {}, child: Column( mainAxisSize: MainAxisSize.max, @@ -47,7 +47,7 @@ class _MhMessageListWidgetState extends State { Container( width: double.infinity, constraints: BoxConstraints( - minHeight: 66.rpx, + minHeight: 60.rpx, ), child: Align( alignment: AlignmentDirectional(-1, 0), @@ -63,94 +63,90 @@ class _MhMessageListWidgetState extends State { ), ), ), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Container( - constraints: BoxConstraints( - minWidth: 30.rpx, - maxWidth: 140.rpx, - ), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: messageInfo['data']['val'] - .map((mapItem) => - _buildInfoItem(context, mapItem['k'] ?? '')) - .toList(), - ), - ), - Container( - constraints: BoxConstraints( - minWidth: 30.rpx, - ), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: messageInfo['data']['val'] - .map((mapItem) => - _buildValueItem(context, mapItem['v'] ?? '')) - .toList(), - ), - ), - ].divide(SizedBox(width: 30.rpx)), - ), - if (messageInfo['type'] == 'app_system') - - // // right: 26.rpx, - // left: 26.rpx, + Row(mainAxisSize: MainAxisSize.max, children: [ Container( - // width: 123.rpx, - height: 61.rpx, - child: CustomCard( - borderRadius: 16.rpx, // 直角 - gradientDirection: GradientDirection.vertical, - colors: [Color(0xFF84F5FF)], - enableAnimation: true, // 有点击缩放动画 - enableGradient: false, // 不用渐变 - onTap: () { - // if (messageInfo['status'] == 1) { - // showConfirmDialog( - // context, Container(), "是否确认接受该设备".tr, - // onConfirm: () async { - // ApiResponse apiResponse = - // await deviceShareController.confirmShare( - // messageInfo['data']['shareCode']); - // if (apiResponse.code == HttpStatusCodes.ok) { - // TopSlideNotification.show( - // context, - // text: apiResponse.msg!, - // textColor: themeController.currentColor.sc2, - // ); - // messageController.getMessageList(); - // messageController.updateAll(); - // } else { - // TopSlideNotification.show( - // context, - // text: apiResponse.msg!, - // textColor: themeController.currentColor.sc9, - // ); - // messageController.getMessageList(); - // messageController.updateAll(); - // } - // }, onCancel: () {}); - // } - Get.toNamed('/messageDetail', arguments: messageInfo); - }, - child: Center( - child: Text( - // getMessageStatus(messageInfo['status']), - "查看详情", - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: Color(0xFF011D33), + constraints: BoxConstraints( + minWidth: 60.rpx, + maxWidth: 140.rpx, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: messageInfo['data']['val'] + .map((mapItem) => + _buildInfoItem(context, mapItem['k'] ?? '')) + .toList(), + ), + ), + Container( + constraints: BoxConstraints( + minWidth: 60.rpx, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: messageInfo['data']['val'] + .map((mapItem) => + _buildValueItem(context, mapItem['v'] ?? '')) + .toList(), + ), + ), + ]), + if (messageInfo['type'] == 'app_system') + Padding( + padding: EdgeInsets.only(top: 28.rpx), + child: Container( + height: 60.rpx, + child: CustomCard( + borderRadius: 16.rpx, // 直角 + gradientDirection: GradientDirection.vertical, + colors: [Color(0xFF84F5FF)], + enableAnimation: true, // 有点击缩放动画 + enableGradient: false, // 不用渐变 + onTap: () { + // if (messageInfo['status'] == 1) { + // showConfirmDialog( + // context, Container(), "是否确认接受该设备".tr, + // onConfirm: () async { + // ApiResponse apiResponse = + // await deviceShareController.confirmShare( + // messageInfo['data']['shareCode']); + // if (apiResponse.code == HttpStatusCodes.ok) { + // TopSlideNotification.show( + // context, + // text: apiResponse.msg!, + // textColor: themeController.currentColor.sc2, + // ); + // messageController.getMessageList(); + // messageController.updateAll(); + // } else { + // TopSlideNotification.show( + // context, + // text: apiResponse.msg!, + // textColor: themeController.currentColor.sc9, + // ); + // messageController.getMessageList(); + // messageController.updateAll(); + // } + // }, onCancel: () {}); + // } + Get.toNamed('/messageDetail', arguments: messageInfo); + }, + child: Center( + child: Text( + // getMessageStatus(messageInfo['status']), + "查看详情", + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: Color(0xFF011D33), + ), ), ), ), ), - ), + ) ], ), ), @@ -161,7 +157,7 @@ class _MhMessageListWidgetState extends State { Widget _buildInfoItem(BuildContext context, String label) { return Container( constraints: BoxConstraints( - minHeight: 62.rpx, + minHeight: 60.rpx, ), child: Align( alignment: AlignmentDirectional(-1, 0), @@ -183,7 +179,7 @@ class _MhMessageListWidgetState extends State { Widget _buildValueItem(BuildContext context, value) { return Container( constraints: BoxConstraints( - minHeight: 62.rpx, + minHeight: 60.rpx, ), child: Align( alignment: AlignmentDirectional(-1, 0), diff --git a/lib/pages/mh_page/applyRepair/apply_repair_success.dart b/lib/pages/mh_page/applyRepair/apply_repair_success.dart index 3eab052..d759b62 100644 --- a/lib/pages/mh_page/applyRepair/apply_repair_success.dart +++ b/lib/pages/mh_page/applyRepair/apply_repair_success.dart @@ -196,7 +196,7 @@ class _ApplyRepairSuccessState extends State { AppConstants().button_container_radius, // 圆角半径 gradientDirection: GradientDirection.vertical, onTap: () async { - Get.toNamed("/repairListPage"); + Get.toNamed("/deviceRepairPage"); }, colors: [ Color(0xFFFCFCFC), diff --git a/lib/pages/mh_page/bluetooth.dart b/lib/pages/mh_page/bluetooth.dart index 36411bc..c754326 100644 --- a/lib/pages/mh_page/bluetooth.dart +++ b/lib/pages/mh_page/bluetooth.dart @@ -11,6 +11,7 @@ import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart'; +import 'dart:ui' as ui; class BluetoothPage extends StatefulWidget { final Map data; @@ -21,10 +22,41 @@ class BluetoothPage extends StatefulWidget { class _BluetoothPageState extends State { late RxMap obsData; + + double _textHalfWidth = 0; @override void initState() { super.initState(); obsData = Map.from(widget.data).obs; // 复制成 obs + String text; + + if (widget.data.containsKey('name') && + widget.data['name'] != null && + widget.data['name'].toString().isNotEmpty) { + text = widget.data['name'].toString(); + } else { + text = '未命名'.tr; + } + + _calculateTextHalfWidth(text); + } + + void _calculateTextHalfWidth(String text) { + final textSpan = TextSpan( + text: text, + style: TextStyle( + fontSize: 40.rpx, + height: 1, + ), + ); + final textPainter = TextPainter( + text: textSpan, + textDirection: ui.TextDirection.ltr, + ); + textPainter.layout(); // 计算文本宽度 + setState(() { + _textHalfWidth = textPainter.width / 2; + }); } BoxConstraints? bodysize; @@ -85,39 +117,53 @@ class _BluetoothPageState extends State { children: [ Column( children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - obsData['name']?.toString() ?? '未命名', - style: TextStyle( - color: Colors.white, - fontSize: 40.rpx, + Container( + width: double.infinity, + child: Stack( + alignment: Alignment.center, + children: [ + Text( + obsData['name']?.toString() ?? '未命名', + style: TextStyle( + color: Colors.white, + fontSize: 40.rpx, + ), + overflow: + TextOverflow.ellipsis, // 超出部分显示省略号 + maxLines: 1, // 限制为单行 ), - ), - SizedBox(width: 27.rpx), - ClickableContainer( - backgroundColor: Colors.transparent, - highlightColor: const Color(0xFF055466), - padding: EdgeInsets.only(left: 0), - onTap: () async { - var x = await Get.toNamed( - "/editBedPage", - arguments: obsData); - if (x != null) { - setState(() { - obsData.addAll(x); // 值更新后主动刷新页面 - }); - } - }, - child: Container( - width: 42.rpx, - height: 42.rpx, - child: SvgPicture.asset( - "assets/img/icon/bluetooth_edit.svg", - color: Colors.white, - ))) - ], + Positioned( + left: + MediaQuery.of(context).size.width / + 2 + + _textHalfWidth + + 22.rpx, + top: 5.rpx, + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: + const Color(0xFF055466), + padding: EdgeInsets.only(left: 0), + onTap: () async { + var x = await Get.toNamed( + "/editBedPage", + arguments: obsData); + if (x != null) { + setState(() { + obsData + .addAll(x); // 值更新后主动刷新页面 + }); + } + }, + child: Container( + width: 42.rpx, + height: 42.rpx, + child: SvgPicture.asset( + "assets/img/icon/bluetooth_edit.svg", + color: Colors.white, + )))) + ], + ), ), const SizedBox(height: 4), @@ -156,17 +202,17 @@ class _BluetoothPageState extends State { ), ], ), - const SizedBox(height: 24), - Expanded( child: ListView( - padding: EdgeInsets.symmetric(horizontal: 30.rpx), + padding: EdgeInsets.only( + left: 30.rpx, right: 30.rpx, bottom: 60.rpx), + reverse: !isBind, children: [ - _buildMenuButton( - context, '详情', "/devicePeopleInfo", - arguments: obsData), if (isBind) ...[ + _buildMenuButton( + context, '详情', "/devicePeopleInfo", + arguments: obsData), _buildMenuButton( context, '人员资料', @@ -185,164 +231,28 @@ class _BluetoothPageState extends State { context, '分享设备', "/deviceSharePage", arguments: obsData), ], - _buildMenuButton( - context, - obsData['bind_type'] == 1 ? '解绑' : '删除', - "", - onTap: () { - if (obsData['bind_type'] == 1) { - // 解绑弹窗 - showUnbindConfirmDialog( - context: context, - title: "是否进行解绑?", - onConfirm: () async { - await deviceListController - .unbindDevice(obsData); - await deviceListController - .getDeviceList(); - MHTHomeController homeController = - Get.find(); - homeController.selectDevcie.value = - ""; - try { - WebviewTestController - webviewTestController = - Get.find(); - webviewTestController - .web.jsbridge?.dart - .unBindDevice(); - } catch (e) { - ef.log("[h5]通知列表更新报错:$e"); - } - Get.toNamed("/mianPageBottomChange"); - // 执行解绑逻辑 - }, - onCancel: () { - // 点击取消后的逻辑 - }, - ); - } else if (obsData['bind_type'] == 2) { - // 删除弹窗 - showDeleteDeviceConfirmDialog( - context: context, - title: "是否进行删除?", - onConfirm: () async { - await deviceListController - .unbindDevice( - obsData, - ); - await deviceListController - .getDeviceList(); - Get.toNamed("/mianPageBottomChange"); - }, - onCancel: () { - // 点击取消后的逻辑 - }, - ); - } - }, - ), + if (!isBind) ...[ + _buildMenuButton( + context, + obsData['bind_type'] == 1 ? '解绑' : '删除', + "", + onTap: () {/*...*/}, + ), + _buildMenuButton( + context, '详情', "/devicePeopleInfo", + arguments: obsData), + ], + if (isBind) ...[ + _buildMenuButton( + context, + obsData['bind_type'] == 1 ? '解绑' : '删除', + "", + onTap: () {/*...*/}, + ), + ], ], ), ), - - // Expanded( - // child: Align( - // alignment: Alignment.bottomCenter, - // child: SingleChildScrollView( - // reverse: true, // 👈 optional,如果你想要滚动时内容从底部弹出 - // child: Column( - // crossAxisAlignment: - // CrossAxisAlignment.stretch, - // mainAxisSize: MainAxisSize.min, - - // children: [ - // _buildMenuButton( - // context, '详情', "/devicePeopleInfo", - // arguments: obsData), - // if (isBind) ...[ - // _buildMenuButton( - // context, - // '人员资料', - // "/peopleInfoPage", - // arguments: obsData, - // ), - // _buildMenuButton( - // context, '房间选择', "/roomPickerPage", - // arguments: obsData), - // _buildMenuButton(context, '设备校准', ""), - // _buildMenuButton(context, '体征传感器', ""), - // _buildMenuButton(context, 'WIFI配置', ""), - // _buildMenuButton( - // context, '睡眠习惯', "/sleepHabitPage"), - // _buildMenuButton( - // context, '分享设备', "/deviceSharePage", - // arguments: obsData), - // ], - // _buildMenuButton( - // context, - // obsData['bind_type'] == 1 ? '解绑' : '删除', - // "", - // onTap: () { - // if (obsData['bind_type'] == 1) { - // // 解绑弹窗 - // showUnbindConfirmDialog( - // context: context, - // title: "是否进行解绑?", - // onConfirm: () async { - // await deviceListController - // .unbindDevice(obsData); - // await deviceListController - // .getDeviceList(); - // MHTHomeController homeController = - // Get.find(); - // homeController - // .selectDevcie.value = ""; - // try { - // WebviewTestController - // webviewTestController = - // Get.find(); - // webviewTestController - // .web.jsbridge?.dart - // .unBindDevice(); - // } catch (e) { - // ef.log("[h5]通知列表更新报错:$e"); - // } - // Get.toNamed( - // "/mianPageBottomChange"); - // // 执行解绑逻辑 - // }, - // onCancel: () { - // // 点击取消后的逻辑 - // }, - // ); - // } else if (obsData['bind_type'] == 2) { - // // 删除弹窗 - // showDeleteDeviceConfirmDialog( - // context: context, - // title: "是否进行删除?", - // onConfirm: () async { - // await deviceListController - // .unbindDevice( - // obsData, - // ); - // await deviceListController - // .getDeviceList(); - // Get.toNamed( - // "/mianPageBottomChange"); - // }, - // onCancel: () { - // // 点击取消后的逻辑 - // }, - // ); - // } - // }, - // ), - // ], - // ), - // ), - // ), - // ), ], ), )), diff --git a/lib/pages/mh_page/component/easychart.dart b/lib/pages/mh_page/component/easychart.dart index a80d77b..013b368 100644 --- a/lib/pages/mh_page/component/easychart.dart +++ b/lib/pages/mh_page/component/easychart.dart @@ -46,146 +46,160 @@ class LineView extends StatelessWidget { bottom: bottomPadding.rpx, ), child: EasyChartView( - size: Size(b.maxWidth, 220.rpx), - drawer: ChartDrawer( - xAxis: ChartAxis( - intent: 44, - entintent: 15, - labels: xLabels, - count: xCount, - ), - yAxis: ChartAxis( - color: Colors.transparent, - isX: false, - intent: 0, - entintent: 45.rpx.toInt(), - labels: yLabels, - count: yCount, - ), - ondrawer: (canvas, size, drawer) { - canvas.scale(1, -1); - ChartLables.drawText( - canvas, - xUnit!, - Offset(drawer.yAxis.labels.first.offset.dx, - -drawer.drawsize.height + 0), - style: TextStyle( - color: Color(0xFFFFFFFF).withOpacity(0.6), - fontSize: 18.rpx, - ), - ); - canvas.scale(1, -1); - // 虚线 - for (var i = 1; - i < drawer.yAxis.labels.first.labels.length; - i++) { - drawer.drawHorizontalDashedLine( + size: Size(b.maxWidth, 220.rpx), + drawer: ChartDrawer( + xAxis: ChartAxis( + intent: 44, + entintent: 15, + labels: xLabels, + count: xCount, + ), + yAxis: ChartAxis( + color: Colors.transparent, + isX: false, + intent: 0, + entintent: 45.rpx.toInt(), + labels: yLabels, + count: yCount, + ), + ondrawer: (canvas, size, drawer) { + canvas.scale(1, -1); + ChartLables.drawText( canvas, - drawer.yAxis.labels.first.steps[i].dy, - drawer.drawsize.width, - dashWidth: 3, - dashSpace: 3, - paint: Paint()..color = Colors.grey, + xUnit!, + Offset(drawer.yAxis.labels.first.offset.dx, + -drawer.drawsize.height + 0), + style: TextStyle( + color: Color(0xFFFFFFFF).withOpacity(0.6), + fontSize: 18.rpx, + ), ); - } - - if (displayMode == ChartDisplayMode.line || - displayMode == ChartDisplayMode.both) { - drawer.drawcurveline( - canvas, - points, - Paint() - ..color = Color(0xFF00C1AA) - ..strokeWidth = 1.5, - ); - drawer.drawpoints( - canvas, - points, - 5, - Paint()..color = Color(0Xff00C1AA), - values: tips, - ); - } - - if (displayMode == ChartDisplayMode.bar || - displayMode == ChartDisplayMode.both) { - for (var i = 0; i < points.length; i++) { - final offset = points[i]; - // final color = (barColors != null && barColors!.length > i) - // ? barColors![i] - // : Colors.yellow.withAlpha(100 + i * 10); // 默认回退 - drawer.drawBar( + canvas.scale(1, -1); + // 虚线 + for (var i = 1; + i < drawer.yAxis.labels.first.labels.length; + i++) { + drawer.drawHorizontalDashedLine( canvas, - Offset(offset.dx, 0), - barWidth, - offset.dy, - - Paint() - ..color = barColors!.length == 0 - ? Colors.white - : stringToColor(barColors![i]), - value: tips[i], + drawer.yAxis.labels.first.steps[i].dy, + drawer.drawsize.width, + dashWidth: 3, + dashSpace: 3, + paint: Paint()..color = Colors.grey, ); } - } - if ((displayMode == ChartDisplayMode.dualBar || - displayMode == ChartDisplayMode.both) && - dualBarPoints != null) { - for (int i = 0; i < dualBarPoints!.length; i++) { - final List bar = dualBarPoints![i]; - if (bar.length < 3) continue; - final Offset deep = bar[0]; // 深睡:起点 -> deep.dy - final Offset light = bar[1]; // 浅睡:起点 -> light.dy - final Offset total = bar[2]; // 总睡眠:起点 -> total.dy - - const String deepColor = "#21AD5D"; // 深睡 - const String lightColor = "#45D989"; // 浅睡 - const String remainColor = "#D3D3D3"; // 剩余 - - // 画深睡 - if (deep.dy > 0) { - drawer.drawBar( - canvas, - Offset(deep.dx, 0), - barWidth, - deep.dy, - value: tips[i], - Paint()..color = stringToColor(deepColor), - ); - } - - // 画浅睡(从 deep.dy 开始) - final double lightHeight = light.dy - deep.dy; - if (lightHeight > 0) { - drawer.drawBar( - canvas, - Offset(light.dx, deep.dy), - barWidth, - lightHeight, - Paint()..color = stringToColor(lightColor), - ); - } - - // 判断是否需要画灰色剩余段和文字 - final double remainHeight = total.dy - light.dy; - if (remainHeight > 0.01) { - // 灰色部分 - drawer.drawBar( - canvas, - Offset(total.dx, light.dy), - barWidth, - remainHeight, - Paint() - ..color = stringToColor(remainColor).withOpacity(0.8), - ); - } - // 若已满,不绘制灰色段、也不显示文字(不做任何处理) + if (displayMode == ChartDisplayMode.line || + displayMode == ChartDisplayMode.both) { + drawer.drawcurveline( + canvas, + points, + Paint() + ..color = Color(0xFF00C1AA) + ..strokeWidth = 1.5, + ); + drawer.drawpoints( + canvas, + points, + 5, + Paint()..color = Color(0Xff00C1AA), + values: tips, + ); } - } - }, - ), - )); + + if (displayMode == ChartDisplayMode.bar || + displayMode == ChartDisplayMode.both) { + for (var i = 0; i < points.length; i++) { + final offset = points[i]; + // final color = (barColors != null && barColors!.length > i) + // ? barColors![i] + // : Colors.yellow.withAlpha(100 + i * 10); // 默认回退 + drawer.drawBar( + canvas, + Offset(offset.dx, 0), + barWidth, + offset.dy, + Paint() + ..color = barColors!.length == 0 + ? Colors.white + : stringToColor(barColors![i]), + value: tips[i], + ); + } + } + if ((displayMode == ChartDisplayMode.dualBar || + displayMode == ChartDisplayMode.both) && + dualBarPoints != null) { + for (int i = 0; i < dualBarPoints!.length; i++) { + final List bar = dualBarPoints![i]; + if (bar.length < 3) continue; + + final Offset deep = bar[0]; // 深睡:起点 -> deep.dy + final Offset light = bar[1]; // 浅睡:起点 -> light.dy + final Offset total = bar[2]; // 总睡眠:起点 -> total.dy + + const String deepColor = "#21AD5D"; // 深睡 + const String lightColor = "#45D989"; // 浅睡 + const String remainColor = "#D3D3D3"; // 剩余 + + // 画深睡 + if (deep.dy > 0) { + drawer.drawBar( + canvas, + Offset(deep.dx, 0), + barWidth, + deep.dy, + value: tips[i], + Paint()..color = stringToColor(deepColor), + ); + } + + // 画浅睡(从 deep.dy 开始) + final double lightHeight = light.dy - deep.dy; + if (lightHeight > 0) { + drawer.drawBar( + canvas, + Offset(light.dx, deep.dy), + barWidth, + lightHeight, + Paint()..color = stringToColor(lightColor), + ); + } + + // 判断是否需要画灰色剩余段和文字 + final double remainHeight = total.dy - light.dy; + if (remainHeight > 0.01) { + // 灰色部分 + drawer.drawBar( + canvas, + Offset(total.dx, light.dy), + barWidth, + remainHeight, + Paint() + ..color = + stringToColor(remainColor).withOpacity(0.8), + ); + } + // 若已满,不绘制灰色段、也不显示文字(不做任何处理) + } + } + }, + ), + onTips: (view, tips) => Container( + padding: EdgeInsets.all(16.rpx), // ✅ 容器内部边距,给文字留空间 + decoration: BoxDecoration( + color: themeController.currentColor.sc5, + borderRadius: BorderRadius.circular(20.rpx), + ), + alignment: Alignment.center, + child: Text( + tips, + style: TextStyle( + color: Color(0XFFFFFFFF), // 多了一个 F,建议改成正确格式 + fontSize: 26.rpx, + ), + ), + ))); }); } } diff --git a/lib/pages/mh_page/device/device.dart b/lib/pages/mh_page/device/device.dart index e924bd9..0ede993 100644 --- a/lib/pages/mh_page/device/device.dart +++ b/lib/pages/mh_page/device/device.dart @@ -357,7 +357,7 @@ class DeviceInfoWidget extends GetView { EdgeInsetsDirectional.fromSTEB( 5, 0, 5, 0), child: Text( - '${device['suname']?.length > 5 ? device['suname'].substring(0, 5) + '...' : device['suname']}', + '${device['source']?.length > 5 ? device['source'].substring(0, 5) + '...' : device['source']}', style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF85F5FF), diff --git a/lib/pages/mh_page/homepage/new_Home_page.dart b/lib/pages/mh_page/homepage/new_Home_page.dart index b3efa66..e89c67b 100644 --- a/lib/pages/mh_page/homepage/new_Home_page.dart +++ b/lib/pages/mh_page/homepage/new_Home_page.dart @@ -900,17 +900,18 @@ class _NewHomePageState extends State { SizedBox(width: 40.rpx), CircleAvatar( radius: 27.rpx, // 可根据需求调整 + backgroundColor: Colors.transparent, backgroundImage: login == 1 ? (userInfoController.model.user!.avatar == null || userInfoController.model.user!.avatar!.isEmpty ? const AssetImage( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", ) : NetworkImage( userInfoController.model.user!.avatar!, )) : const AssetImage( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", ), ), SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 @@ -923,17 +924,18 @@ class _NewHomePageState extends State { SizedBox(width: 40.rpx), CircleAvatar( radius: 27.rpx, // 可根据需求调整 + backgroundColor: Colors.transparent, backgroundImage: login == 1 ? (userInfoController.model.user!.avatar == null || userInfoController.model.user!.avatar!.isEmpty ? const AssetImage( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", ) : NetworkImage( userInfoController.model.user!.avatar!, )) : const AssetImage( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", ), ), SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 diff --git a/lib/pages/mh_page/message/messageDetail.dart b/lib/pages/mh_page/message/messageDetail.dart index 01fb5b4..bc7b95a 100644 --- a/lib/pages/mh_page/message/messageDetail.dart +++ b/lib/pages/mh_page/message/messageDetail.dart @@ -192,9 +192,8 @@ class _MessageDetailPageState extends State { getStatusText(widget.data['status']), style: TextStyle( fontFamily: 'Readex Pro', - color: widget.data['data']['status'] == 1 - ? Colors.white - : Color(0xFF929699), + color: + widget.data['status'] == 1 ? Colors.white : Color(0xFF929699), fontSize: 26.rpx, letterSpacing: 0, ), diff --git a/lib/pages/mh_page/new_mine_page.dart b/lib/pages/mh_page/new_mine_page.dart index 96205fa..df17443 100644 --- a/lib/pages/mh_page/new_mine_page.dart +++ b/lib/pages/mh_page/new_mine_page.dart @@ -141,7 +141,7 @@ class _MinePageState extends State { userInfoController .model.user!.avatar!.isEmpty ? Image.asset( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", fit: BoxFit.cover, ) : Image.network( @@ -149,7 +149,7 @@ class _MinePageState extends State { fit: BoxFit.cover, )) : Image.asset( - "assets/images/default_avatar.png", + "assets/images/mine_avatar.png", fit: BoxFit.cover, ), ), diff --git a/lib/pages/mh_page/repair_history_widget.dart b/lib/pages/mh_page/repair_history_widget.dart index 489374b..578af95 100644 --- a/lib/pages/mh_page/repair_history_widget.dart +++ b/lib/pages/mh_page/repair_history_widget.dart @@ -64,7 +64,7 @@ class RepairHistoryWidget extends GetView { children: [ Text( repairListController.model.repairList[index]['device'] - [0]['mac'] ?? + ['mac'] ?? '', style: TextStyle( color: Colors.white, fontSize: 30.rpx, height: 1), diff --git a/lib/pages/sleep_report/component/WeekDataWidget.dart b/lib/pages/sleep_report/component/WeekDataWidget.dart index f01819e..88b624e 100644 --- a/lib/pages/sleep_report/component/WeekDataWidget.dart +++ b/lib/pages/sleep_report/component/WeekDataWidget.dart @@ -193,7 +193,7 @@ Widget WeekDataWidget( offset, textAlign: TextAlign.center, style: TextStyle( - color: Color(0xFFFFFFFF).withOpacity(0.6), + color: Color(0xFFFFFFFF).withOpacity(0.06), fontSize: 18.rpx), ); }, diff --git a/lib/pages/sleep_report/component/WeekSleepScoreWidget.dart b/lib/pages/sleep_report/component/WeekSleepScoreWidget.dart index c4e5b4b..41060b4 100644 --- a/lib/pages/sleep_report/component/WeekSleepScoreWidget.dart +++ b/lib/pages/sleep_report/component/WeekSleepScoreWidget.dart @@ -88,7 +88,7 @@ class AvgSleepScoreWidget extends StatelessWidget { Text( sleepReport['score']?['max']?.toString() ?? '--', style: TextStyle( - color: stringToColor("#FF9F66"), + color: Colors.white, fontSize: 48.rpx, ), ), diff --git a/lib/pages/sleep_report/new_sleep_report_page.dart b/lib/pages/sleep_report/new_sleep_report_page.dart index 30d4ee1..73a3782 100644 --- a/lib/pages/sleep_report/new_sleep_report_page.dart +++ b/lib/pages/sleep_report/new_sleep_report_page.dart @@ -37,6 +37,7 @@ class _NewSleepReportPageState extends State { final GlobalKey heartRateCardKey = GlobalKey(); final GlobalKey breatheCardKey = GlobalKey(); final ScrollController _scrollController = ScrollController(); + final RxBool isRightLimit = false.obs; @override void didUpdateWidget(NewSleepReportPage oldWidget) { @@ -590,176 +591,180 @@ class _NewSleepReportPageState extends State { child: getTimeWidget(), ), ), - if (widget.data['person_show'] == null || - widget.data['person_show'] != false) - Padding( - padding: EdgeInsetsDirectional.fromSTEB( - 30.rpx, 0.rpx, 30.rpx, 51.rpx), - child: ClickableContainer( - backgroundColor: - widget.data['backgroundColor'] != null - ? widget.data['backgroundColor'] - : themeController.currentColor.sc5, - highlightColor: - themeController.currentColor.sc5, // 或你希望的点击水波纹颜色 - borderRadius: AppConstants() - .normal_container_radius, // 如果你想加圆角可以设置 eg. 12.rpx - padding: EdgeInsets.zero, - onTap: () {}, - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - flex: 2, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.end, - children: [ - Text( - '姓名'.tr, - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc4, + if (widget.data['person_show'] == null || + widget.data['person_show'] != false) + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0.rpx, 30.rpx, 51.rpx), + child: ClickableContainer( + backgroundColor: + widget.data['backgroundColor'] != null + ? widget.data['backgroundColor'] + : themeController.currentColor.sc5, + highlightColor: themeController + .currentColor.sc5, // 或你希望的点击水波纹颜色 + borderRadius: AppConstants() + .normal_container_radius, // 如果你想加圆角可以设置 eg. 12.rpx + padding: EdgeInsets.zero, + onTap: () {}, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + flex: 2, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Text( + '姓名'.tr, + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc4, + ), ), - ), - Text( - '年龄'.tr, - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc4, + Text( + '年龄'.tr, + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc4, + ), ), - ), - ].divide(SizedBox(height: 34.rpx)), - ), - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - (widget.data['person']?['name'] - ?.toString() - .trim() - .isNotEmpty ?? - false) - ? widget - .data['person']!['name'] - .toString() - : '未知数据'.tr, - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc3, + ].divide(SizedBox(height: 34.rpx)), + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + (widget.data['person']?['name'] + ?.toString() + .trim() + .isNotEmpty ?? + false) + ? widget + .data['person']!['name'] + .toString() + : '未知数据'.tr, + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc3, + ), ), - ), - Text( - '${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(widget.data['person']?['birthday'])) ?? '未知数据'.tr}', - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc3, + Text( + '${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(widget.data['person']?['birthday'])) ?? '未知数据'.tr}', + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc3, + ), ), - ), - ].divide(SizedBox(height: 34.rpx)), - ), - ] - .divide(SizedBox(width: 33.rpx)) - .addToStart(SizedBox(width: 37.rpx)), - ), - ] - .addToStart(SizedBox(height: 36.rpx)) - .addToEnd(SizedBox(height: 36.rpx)), + ].divide(SizedBox(height: 34.rpx)), + ), + ] + .divide(SizedBox(width: 33.rpx)) + .addToStart( + SizedBox(width: 37.rpx)), + ), + ] + .addToStart(SizedBox(height: 36.rpx)) + .addToEnd(SizedBox(height: 36.rpx)), + ), ), - ), - Flexible( - flex: 3, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Column( - crossAxisAlignment: - CrossAxisAlignment.end, - children: [ - Text( - '设备ID'.tr, - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc4, + Flexible( + flex: 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + Text( + '设备ID'.tr, + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc4, + ), ), - ), - Text( - '体重'.tr, - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc4, + Text( + '体重'.tr, + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc4, + ), ), - ), - ].divide(SizedBox(height: 34.rpx)), - ), - Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - '${widget.data['code'] ?? '未知数据'.tr}', - // "D11250300003", - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc3, + ].divide(SizedBox(height: 34.rpx)), + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + '${widget.data['code'] ?? '未知数据'.tr}', + // "D11250300003", + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc3, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - Text( - '${widget.data['person']?['weight'] ?? '未知数据'.tr}kg', - style: TextStyle( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - color: themeController - .currentColor.sc3, + Text( + '${widget.data['person']?['weight'] ?? '未知数据'.tr}kg', + style: TextStyle( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: themeController + .currentColor.sc3, + ), ), - ), - ].divide(SizedBox(height: 34.rpx)), - ), - ] - .divide(SizedBox(width: 33.rpx)) - .addToStart(SizedBox(width: 37.rpx)), - ), - ] - .addToStart(SizedBox(height: 36.rpx)) - .addToEnd(SizedBox(height: 36.rpx)), + ].divide(SizedBox(height: 34.rpx)), + ), + ] + .divide(SizedBox(width: 33.rpx)) + .addToStart( + SizedBox(width: 37.rpx)), + ), + ] + .addToStart(SizedBox(height: 36.rpx)) + .addToEnd(SizedBox(height: 36.rpx)), + ), ), - ), - ], + ], + ), ), ), - ), (sleepReport.value == null || sleepReport.value.isEmpty) ? Container( child: NullDataWidget(), @@ -778,7 +783,6 @@ class _NewSleepReportPageState extends State { )), ); }), - ), ), ), @@ -829,6 +833,7 @@ class _NewSleepReportPageState extends State { } void onLeftArrowTap() { + isRightLimit.value = false; if (type == 1) { sleepReportController.selectedDate.value = selectedDate.subtract(const Duration(days: 1)); @@ -877,53 +882,89 @@ class _NewSleepReportPageState extends State { } void onRightArrowTap() { + final now = DateTime.now(); + final today = DateTime(now.year, now.month, now.day); + DateTime targetDate = selectedDate; + + + if (type == 1) { - sleepReportController.selectedDate.value = - selectedDate.add(const Duration(days: 1)); + final nextDate = selectedDate.add(const Duration(days: 1)); + if (!nextDate.isAfter(today)) { + targetDate = nextDate; + } else { + isRightLimit.value = true; + return; + } } else if (type == 2) { - sleepReportController.selectedDate.value = - selectedDate.add(const Duration(days: 7)); + final currentWeekday = today.weekday; // 1=周一,7=周日 + final currentWeekEnd = today.add(Duration(days: 7 - currentWeekday)); + final nextWeek = selectedDate.add(const Duration(days: 7)); + + if (!nextWeek.isAfter(currentWeekEnd)) { + targetDate = nextWeek; + } else { + isRightLimit.value = true; + return; + } } else if (type == 3) { - sleepReportController.selectedDate.value = DateTime( + final currentMonthEnd = DateTime(today.year, today.month + 1, 0); + final nextMonth = DateTime( selectedDate.year, selectedDate.month + 1, selectedDate.day, ); + + if (!nextMonth.isAfter(currentMonthEnd)) { + final correctedDay = DateTime( + nextMonth.year, + nextMonth.month + 1, + 0, + ).day; + + targetDate = DateTime( + nextMonth.year, + nextMonth.month, + nextMonth.day > correctedDay ? correctedDay : nextMonth.day, + ); + } else { + isRightLimit.value = true; + return; + } } - calendarController.selectedDate.value = - sleepReportController.selectedDate.value; - String data = MyUtils.formatDate(calendarController.selectedDate.value!); + + // 👉 更新数据并请求 + sleepReportController.selectedDate.value = targetDate; + calendarController.selectedDate.value = targetDate; + + String data = MyUtils.formatDate(targetDate); requestWithLog( - logTitle: "查询睡眠报告", - method: MyHttpMethod.get, - queryUrl: - "https://sleepdata.he-info.com/api/analysis/sleep/analysis?mac=${widget.data['mac']}&time=${data}&type=${sleepReportController.model.type}", - onSuccess: (res) { - print(res); - sleepReportController.sleepReport.value = res.data; - sleepReportController.updateAll(); - }, - onFailure: (res) { - if (MainPageBBottomChange.getCurrentIndex() != null) { - if (MainPageBBottomChange.getCurrentIndex() == 1) { - TopSlideNotification.show(context, - text: res.msg!, - textColor: themeController.currentColor.sc9); - } - } else { - TopSlideNotification.show(context, - text: res.msg!, textColor: themeController.currentColor.sc9); - } - sleepReportController.sleepReport.value = {}; - sleepReportController.updateAll(); - print(res); - }); + logTitle: "查询睡眠报告", + method: MyHttpMethod.get, + queryUrl: + "https://sleepdata.he-info.com/api/analysis/sleep/analysis?mac=${widget.data['mac']}&time=${data}&type=${sleepReportController.model.type}", + onSuccess: (res) { + print(res); + sleepReportController.sleepReport.value = res.data; + sleepReportController.updateAll(); + }, + onFailure: (res) { + final msg = res.msg!; + TopSlideNotification.show( + context, + text: msg, + textColor: themeController.currentColor.sc9, + ); + sleepReportController.sleepReport.value = {}; + sleepReportController.updateAll(); + }, + ); + sleepReportController.updateAll(); calendarController.updateAll(); } - - void onChangeArrowTap() { + void onChangeArrowTap() { if (type == 1) { sleepReportController.selectedDate.value = selectedDate.subtract(const Duration(days: 1)); @@ -971,8 +1012,6 @@ class _NewSleepReportPageState extends State { calendarController.updateAll(); } - - return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -985,9 +1024,9 @@ class _NewSleepReportPageState extends State { padding: EdgeInsets.all(10.rpx), borderRadius: 8.rpx, onTap: onLeftArrowTap, - child: SizedBox( - width: 9.rpx, - height: 14.rpx, + child: Container( + width: 30.rpx, + height: 30.rpx, child: SvgPicture.asset( 'assets/img/icon/arrow_left.svg', color: themeController.currentColor.sc3, @@ -1004,21 +1043,36 @@ class _NewSleepReportPageState extends State { ), ), ), - ClickableContainer( - backgroundColor: Colors.transparent, - highlightColor: themeController.currentColor.sc3, - padding: EdgeInsets.all(10.rpx), - borderRadius: 8.rpx, - onTap: onRightArrowTap, - child: SizedBox( - width: 9.rpx, - height: 14.rpx, - child: SvgPicture.asset( - 'assets/img/icon/arrow_right.svg', - color: themeController.currentColor.sc3, - ), - ), - ), + // ClickableContainer( + // backgroundColor: Colors.transparent, + // highlightColor: themeController.currentColor.sc3, + // padding: EdgeInsets.all(10.rpx), + // borderRadius: 8.rpx, + // onTap: onRightArrowTap, + // child: Container( + // width: 30.rpx, + // height: 30.rpx, + // child: SvgPicture.asset( + // 'assets/img/icon/arrow_right.svg', + // color: themeController.currentColor.sc3, + // ), + // ), + // ), + Obx(() => ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: themeController.currentColor.sc3, + padding: EdgeInsets.all(10.rpx), + borderRadius: 8.rpx, + onTap: isRightLimit.value ? () {} : onRightArrowTap, + child: Container( + width: 30.rpx, + height: 30.rpx, + child: SvgPicture.asset('assets/img/icon/arrow_right.svg', + color: isRightLimit.value + ? Color(0xFF929699) + : Color(0xFFFFFFFF)), + ), + )) ], ), ClickableContainer(