diff --git a/assets/langs/en_US.json b/assets/langs/en_US.json index 5442f23..cbeae23 100644 --- a/assets/langs/en_US.json +++ b/assets/langs/en_US.json @@ -299,7 +299,7 @@ "确认": "Confirm", "输入关键字": "Enter keywords", "搜索": "Search", - "名称": "Name:", + "名称": "Name", "账号": "Account:", "分享时间": "Share time", "设备校准": "Device calibration", @@ -418,7 +418,7 @@ "昨日数据": "today", "次": "times", "秒": "sec", - "暂无": "none", + "暂无": "None", "失败": "Failed", "关于我们": "About Us", "周一": "Mon", @@ -433,7 +433,7 @@ "年龄": "Age", "设备ID": "Device ID", "体重": "Weight", - "分": "Points", + "分": "", "位置权限说明": "Location Permission Description", "获得位置信息,连接附近的蓝牙设备与推荐附近门店": "Obtain location information, connect to nearby Bluetooth devices, and recommend nearby stores", "蓝牙权限说明": "Bluetooth Permission Description", @@ -497,7 +497,7 @@ "次/分": "times/min", "毫秒": "ms", "起床时间:": "Wake Up:", - "入睡时间:": "Sleep Time:", + "入睡时间:": "Sleep Time", "睡眠分数与上月分数进行对比,是通过量化分析近期睡眠质量变化,可了解自身睡眠状态的波动情况,进而调整用户的作息习惯。": "The sleep score is compared with last month’s score to analyze recent changes in sleep quality, helping you understand fluctuations and adjust your routine accordingly.", "睡眠分数与上周分数进行对比,是通过量化分析近期睡眠质量变化,可了解自身睡眠状态的波动情况,进而调整用户的作息习惯。": "The sleep score is compared with last week's score to analyze changes in sleep quality, helping you understand fluctuations and adjust your routine.", "本月睡眠时长": "Monthly Sleep Duration", @@ -523,5 +523,8 @@ "四": "Thu", "五": "Fri", "六": "Sat", - "日": "Sun" + "日": "Sun", + "icp备案号": "ICP备案号:皖ICP备2024068219号-1A", + "公司信息": "Copyright © 2022-2025 Jiaxing Taihe Information Technology Co., Ltd. All rights reserved.", + "当前属于": "Current" } \ No newline at end of file diff --git a/assets/langs/zh_CN.json b/assets/langs/zh_CN.json index 2e1eda4..b194016 100644 --- a/assets/langs/zh_CN.json +++ b/assets/langs/zh_CN.json @@ -531,5 +531,8 @@ "四": "四", "五": "五", "六": "六", - "日": "日" + "日": "日", + "可用WLAN": "可用WLAN","请输入人员名称":"请输入人员名称", + "icp备案号":"ICP备案号:皖ICP备2024068219号-1A", + "公司信息":"Copyright © 2022-2025 嘉兴太和信息技术有限责任公司 版权所有" } \ No newline at end of file diff --git a/assets/langs/zh_TW.json b/assets/langs/zh_TW.json index 81015a2..c8141d4 100644 --- a/assets/langs/zh_TW.json +++ b/assets/langs/zh_TW.json @@ -521,5 +521,8 @@ "四": "四", "五": "五", "六": "六", - "日": "日" + "日": "日", + "icp备案号": "ICP备案号:皖ICP备2024068219号-1A", + "公司信息":"Copyright © 2022-2025 嘉興太和信息技術有限責任公司 版權所有", + "当前属于": "當前" } \ No newline at end of file diff --git a/lib/common/color/ServiceConstant.dart b/lib/common/color/ServiceConstant.dart index 0967deb..408e633 100644 --- a/lib/common/color/ServiceConstant.dart +++ b/lib/common/color/ServiceConstant.dart @@ -49,5 +49,5 @@ class ServiceConstant { static const String personnel_info = "/api/personnel/info"; //人员信息列表 static const String policy_url = - "https://wyf.it.real.he-info.cn:94/apk/policy";//协议地址 + "https://vsbst-api.he-info.cn/vsbs_sotrage/privacy-scheme/"; //协议地址 } diff --git a/lib/common/color/appConstants.dart b/lib/common/color/appConstants.dart index 19c21cc..3000150 100644 --- a/lib/common/color/appConstants.dart +++ b/lib/common/color/appConstants.dart @@ -84,20 +84,20 @@ String getPrivacy(int type) { } else if (AppConstants().ent_type == APPPackageType.TH.code) { if (type == 1) { return ServiceConstant.policy_url + - "/th" + + "/theh" + "/th_privacy_policy_$language.html"; } return ServiceConstant.policy_url + - "/th" + + "/theh" + "/th_user_policy_$language.html"; } else { if (type == 1) { return ServiceConstant.policy_url + - "/th" + + "/theh" + "/th_privacy_policy_$language.html"; } return ServiceConstant.policy_url + - "/th" + + "/theh" + "/th_user_policy_$language.html"; } } diff --git a/lib/component/base/SleepCalendarWidget.dart b/lib/component/base/SleepCalendarWidget.dart index e2ebe25..9a1dd7e 100644 --- a/lib/component/base/SleepCalendarWidget.dart +++ b/lib/component/base/SleepCalendarWidget.dart @@ -5,9 +5,8 @@ import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart'; -import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/date/CalendarController.dart'; -import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; + import 'SleepdateWidget.dart'; class SleepCalendarWidget extends StatefulWidget { diff --git a/lib/component/home_page/SleepDataModuleWidget.dart b/lib/component/home_page/SleepDataModuleWidget.dart index 71c1abe..92588e8 100644 --- a/lib/component/home_page/SleepDataModuleWidget.dart +++ b/lib/component/home_page/SleepDataModuleWidget.dart @@ -115,16 +115,42 @@ class _SleepDataModuleWidgetState extends State { SizedBox( height: 37.rpx, ), - Text( - "${widget.data['value']}" + - ((widget.data['unit'] == null || - widget.data['unit'].toString().isEmpty) - ? '' - : widget.data['unit']), - style: TextStyle( - color: stringToColor("${widget.data['color']}"), - fontSize: 60.rpx, - ), + // Text( + // "${widget.data['value']}" + + // ((widget.data['unit'] == null || + // widget.data['unit'].toString().isEmpty) + // ? '' + // : widget.data['unit']), + // style: TextStyle( + // color: stringToColor("${widget.data['color']}"), + // fontSize: 60.rpx, + // ), + // ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + "${widget.data['value']}", + style: TextStyle( + color: stringToColor("${widget.data['color']}"), + fontSize: 60.rpx, + ), + ), + if (widget.data['unit'] != null && + widget.data['unit'].toString().isNotEmpty) + Padding( + padding: EdgeInsets.only(left: 4.rpx), // 添加适当间距 + child: Text( + "${widget.data['unit']}", + style: TextStyle( + color: stringToColor("${widget.data['color']}"), + fontSize: 30.rpx, // 单位使用较小字号 + ), + ), + ), + ], ), SizedBox( height: 81.rpx, @@ -288,7 +314,6 @@ class _SleepDataModuleWidgetState extends State { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( child: Text.rich( TextSpan( @@ -323,7 +348,6 @@ class _SleepDataModuleWidgetState extends State { overflow: TextOverflow.ellipsis, ), ), - if (widget.data['level'] != null) ClickableContainer( backgroundColor: (widget.data['color'] == null || diff --git a/lib/pages/login/other_login.dart b/lib/pages/login/other_login.dart index 3e73901..46bbc99 100644 --- a/lib/pages/login/other_login.dart +++ b/lib/pages/login/other_login.dart @@ -53,13 +53,15 @@ class _OtherLoginPageState extends State { // 协议2点击事件逻辑 print('点击了协议2'); // Get.to(() => UserSchemePage()); - Get.toNamed("/userSchemePage"); + // Get.toNamed("/userSchemePage"); + Get.toNamed("/userPolicyPageNew", arguments: getPrivacy(2)); }; _tapRecognizer4 = TapGestureRecognizer() ..onTap = () { // 协议4点击事件逻辑 - print('点击了协议4'); - Get.toNamed("/privacyPage"); + // print('点击了协议4'); + // Get.toNamed("/privacyPage"); + Get.toNamed("/privacyPolicyPageNew", arguments: getPrivacy(1)); }; super.initState(); LoginController loginController = Get.find(); diff --git a/lib/pages/sleep_report/chart/DataShowWidget.dart b/lib/pages/sleep_report/chart/DataShowWidget.dart index cf5c155..475053d 100644 --- a/lib/pages/sleep_report/chart/DataShowWidget.dart +++ b/lib/pages/sleep_report/chart/DataShowWidget.dart @@ -50,7 +50,7 @@ class _DataShowWidgetState extends State { children: [ // 放入传入的 widget1 Container( - width: MediaQuery.sizeOf(context).width * 0.35, // 固定宽度 + width: MediaQuery.sizeOf(context).width * 0.33, // 固定宽度 decoration: BoxDecoration(), child: Align( alignment: Alignment.centerLeft, @@ -90,7 +90,7 @@ class _DataShowWidgetState extends State { ), // 放入传入的 widget4 Container( - width: MediaQuery.sizeOf(context).width * 0.1, // 固定宽度 + width: MediaQuery.sizeOf(context).width * 0.12, // 固定宽度 decoration: BoxDecoration(), child: Align( alignment: widget.alignment == MainAxisAlignment.start diff --git a/lib/pages/sleep_report/chart/ScatterPlotChart.dart b/lib/pages/sleep_report/chart/ScatterPlotChart.dart index 2d66531..0304f72 100644 --- a/lib/pages/sleep_report/chart/ScatterPlotChart.dart +++ b/lib/pages/sleep_report/chart/ScatterPlotChart.dart @@ -23,11 +23,11 @@ class ScatterPlotChart extends StatelessWidget { // 计算向上取整后的最大值 // double xMaxCeil = (xMax / divisions).ceil() * divisions.toDouble(); double temp = (xMax / divisions).ceil().toDouble(); // 计算向上取整后的每个分区的最大值 - double xMaxCeil = (((temp / 100).ceil()) * 100 * (divisions - 1)) + double xMaxCeil = (((temp / 100).ceil()) * 100 * (divisions)) .toDouble(); // 向百取整并乘以 divisions double tempy = (yMax / divisions).ceil().toDouble(); // 计算向上取整后的每个分区的最大值 double yMaxCeil = - (((tempy / 100).ceil()) * 100 * (divisions - 1)).toDouble(); + (((tempy / 100).ceil()) * 100 * (divisions)).toDouble(); return SizedBox( child: ScatterChart( diff --git a/lib/pages/sleep_report/chart/SnoreWaveform.dart b/lib/pages/sleep_report/chart/SnoreWaveform.dart index b99bcd2..904e9ce 100644 --- a/lib/pages/sleep_report/chart/SnoreWaveform.dart +++ b/lib/pages/sleep_report/chart/SnoreWaveform.dart @@ -1,3 +1,280 @@ +// import 'dart:ui' as ui; +// import 'package:flutter/material.dart'; +// import 'package:flutterflow_ui/flutterflow_ui.dart'; +// import 'package:vbvs_app/common/util/FitTool.dart'; +// import 'package:vbvs_app/common/util/MyUtils.dart'; +// import 'package:intl/intl.dart'; + +// class SnoreChartContainer extends StatelessWidget { +// final List snoreValues; +// final List barData; +// final List showLabel; +// final int startTime; +// final int endTime; + +// const SnoreChartContainer({ +// required this.snoreValues, +// required this.barData, +// required this.showLabel, +// required this.startTime, +// required this.endTime, +// super.key, +// }); + +// @override +// Widget build(BuildContext context) { +// return Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// SnoreBarOverlay( +// barData: barData, +// showLabel: showLabel, +// startTime: startTime, +// endTime: endTime, +// ), +// Container(height: 32.rpx), +// Container( +// height: 23.rpx, +// child: SnoreWaveform( +// snoreValues: snoreValues, +// startTime: startTime, +// endTime: endTime, +// ), +// ), +// ], +// ); +// } +// } + +// class SnoreBarOverlay extends StatelessWidget { +// final List barData; +// final List showLabel; // ✅ 加入 +// final int startTime; +// final int endTime; + +// const SnoreBarOverlay({ +// required this.barData, +// required this.showLabel, // ✅ 加入 +// required this.startTime, +// required this.endTime, +// super.key, +// }); + +// @override +// Widget build(BuildContext context) { +// const double barHeight = 50; +// return SizedBox( +// height: barHeight, +// child: CustomPaint( +// size: Size(double.infinity, barHeight), +// painter: SnoreBarPainter( +// barData: barData, +// showLabel: showLabel, // ✅ 加入 +// startTime: startTime, +// endTime: endTime, +// ), +// ), +// ); +// } +// } + +// class SnoreBarPainter extends CustomPainter { +// final List barData; +// final List showLabel; // ✅ 加入 +// final int startTime; +// final int endTime; + +// SnoreBarPainter({ +// required this.barData, +// required this.showLabel, // ✅ 加入 +// required this.startTime, +// required this.endTime, +// }); + +// @override +// void paint(Canvas canvas, Size size) { +// final double width = size.width; +// final double height = size.height; +// final double pixelPerMs = width / (endTime - startTime); + +// for (var item in barData) { +// final int st = item['st']; +// final int et = item['et']; +// final int type = item['type']; + +// // 查找匹配的颜色 +// final match = showLabel.firstWhere( +// (e) => e['type'] == type, +// orElse: () => null, +// ); + +// Color barColor = Colors.transparent; +// if (match != null) { +// final dynamic colorStr = match['color']; +// if (colorStr != null && colorStr.toString().isNotEmpty) { +// barColor = stringToColor(colorStr); +// } +// } + +// final Paint barPaint = Paint() +// ..color = barColor +// ..style = PaintingStyle.fill; + +// final double leftX = (st - startTime) * pixelPerMs; +// final double rightX = (et - startTime) * pixelPerMs; +// final double barWidth = rightX - leftX; + +// final double barHeight = (type + 5).toDouble() * 8; +// final double top = height - barHeight; + +// final rect = Rect.fromLTWH(leftX, top, barWidth, barHeight); +// canvas.drawRect(rect, barPaint); +// } +// } + +// @override +// bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +// } + +// class SnoreWaveform extends StatelessWidget { +// final List snoreValues; +// final int startTime; +// final int endTime; + +// const SnoreWaveform({ +// required this.snoreValues, +// required this.startTime, +// required this.endTime, +// super.key, +// }); + +// @override +// Widget build(BuildContext context) { +// return SizedBox( +// height: 150, +// child: CustomPaint( +// size: Size(double.infinity, 150), +// painter: SnoreWaveformPainter( +// snoreValues: snoreValues, +// startTime: startTime, +// endTime: endTime, +// ), +// ), +// ); +// } +// } + +// class SnoreWaveformPainter extends CustomPainter { +// final List snoreValues; +// final int startTime; +// final int endTime; + +// SnoreWaveformPainter({ +// required this.snoreValues, +// required this.startTime, +// required this.endTime, +// }); + +// @override +// void paint(Canvas canvas, Size size) { +// final double width = size.width; +// final double height = size.height; +// final double centerY = height / 2; +// final double totalDuration = (endTime - startTime).toDouble(); +// final double pixelPerMs = width / totalDuration; + +// final Paint wavePaint = Paint() +// ..color = stringToColor("#8E7DEF").withOpacity(0.8) +// ..strokeWidth = 1.5 +// ..style = PaintingStyle.stroke; + +// final Path upperPath = Path(); +// final Path lowerPath = Path(); + +// // ✅ 获取最大值用于自适应比例 +// double maxValue = snoreValues.fold(0, (prev, e) { +// final value = e["value"]?.toDouble() ?? 0; +// return value > prev ? value : prev; +// }); + +// // ✅ 自适应缩放比例,限制波形最大高度为 height * 0.45 +// final double maxWaveHeight = height * 1; +// final double scaleY = maxValue > 0 ? (maxWaveHeight / maxValue) : 1; + +// for (int i = 0; i < snoreValues.length; i++) { +// final timestamp = snoreValues[i]["st"]; +// final value = snoreValues[i]["value"]?.toDouble() ?? 0; + +// final x = (timestamp - startTime) * pixelPerMs; +// final y = centerY - value * scaleY; +// final yMirror = centerY + value * scaleY; + +// if (i == 0) { +// upperPath.moveTo(x, y); +// lowerPath.moveTo(x, yMirror); +// } else { +// upperPath.lineTo(x, y); +// lowerPath.lineTo(x, yMirror); +// } +// } + +// canvas.drawPath(upperPath, wavePaint); +// canvas.drawPath(lowerPath, wavePaint); + +// // ✅ 最后绘制中心线,防止被覆盖 +// final Paint axisPaint = Paint() +// ..color = Colors.grey.withOpacity(0.6) +// ..strokeWidth = 0.5; +// canvas.drawLine(Offset(0, centerY), Offset(width, centerY), axisPaint); + +// // ✅ 时间刻度绘制 +// final textPainter = TextPainter( +// textAlign: TextAlign.center, +// textDirection: ui.TextDirection.ltr, +// ); + +// final int hourMs = 60 * 60 * 1000; +// for (int t = startTime; t < endTime; t += hourMs) { +// double x = (t - startTime) * pixelPerMs; + +// DateTime dt = DateTime.fromMillisecondsSinceEpoch(t); +// String label = t == startTime +// ? DateFormat('HH:mm').format(dt) +// : DateFormat('h').format(dt); // 12小时制 + +// textPainter.text = TextSpan( +// text: label, +// style: TextStyle(fontSize: 10, color: Colors.grey), +// ); +// textPainter.layout(); +// textPainter.paint( +// canvas, +// Offset(x - textPainter.width / 2, height + 2), // 标签显示在底部 +// ); +// } + +// // ✅ 画终点时间 +// { +// double x = (endTime - startTime) * pixelPerMs; +// DateTime dt = DateTime.fromMillisecondsSinceEpoch(endTime); +// String label = DateFormat('HH:mm').format(dt); + +// textPainter.text = TextSpan( +// text: label, +// style: TextStyle(fontSize: 10, color: Colors.grey), +// ); +// textPainter.layout(); +// textPainter.paint( +// canvas, +// Offset(x - textPainter.width / 2, height + 2), +// ); +// } +// } + +// @override +// bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +// } + import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; @@ -48,13 +325,13 @@ class SnoreChartContainer extends StatelessWidget { class SnoreBarOverlay extends StatelessWidget { final List barData; - final List showLabel; // ✅ 加入 + final List showLabel; final int startTime; final int endTime; const SnoreBarOverlay({ required this.barData, - required this.showLabel, // ✅ 加入 + required this.showLabel, required this.startTime, required this.endTime, super.key, @@ -69,7 +346,7 @@ class SnoreBarOverlay extends StatelessWidget { size: Size(double.infinity, barHeight), painter: SnoreBarPainter( barData: barData, - showLabel: showLabel, // ✅ 加入 + showLabel: showLabel, startTime: startTime, endTime: endTime, ), @@ -80,13 +357,13 @@ class SnoreBarOverlay extends StatelessWidget { class SnoreBarPainter extends CustomPainter { final List barData; - final List showLabel; // ✅ 加入 + final List showLabel; final int startTime; final int endTime; SnoreBarPainter({ required this.barData, - required this.showLabel, // ✅ 加入 + required this.showLabel, required this.startTime, required this.endTime, }); @@ -102,7 +379,6 @@ class SnoreBarPainter extends CustomPainter { final int et = item['et']; final int type = item['type']; - // 查找匹配的颜色 final match = showLabel.firstWhere( (e) => e['type'] == type, orElse: () => null, @@ -191,13 +467,11 @@ class SnoreWaveformPainter extends CustomPainter { final Path upperPath = Path(); final Path lowerPath = Path(); - // ✅ 获取最大值用于自适应比例 double maxValue = snoreValues.fold(0, (prev, e) { final value = e["value"]?.toDouble() ?? 0; return value > prev ? value : prev; }); - // ✅ 自适应缩放比例,限制波形最大高度为 height * 0.45 final double maxWaveHeight = height * 1; final double scaleY = maxValue > 0 ? (maxWaveHeight / maxValue) : 1; @@ -221,54 +495,104 @@ class SnoreWaveformPainter extends CustomPainter { canvas.drawPath(upperPath, wavePaint); canvas.drawPath(lowerPath, wavePaint); - // ✅ 最后绘制中心线,防止被覆盖 final Paint axisPaint = Paint() ..color = Colors.grey.withOpacity(0.6) ..strokeWidth = 0.5; canvas.drawLine(Offset(0, centerY), Offset(width, centerY), axisPaint); - // ✅ 时间刻度绘制 final textPainter = TextPainter( textAlign: TextAlign.center, textDirection: ui.TextDirection.ltr, ); final int hourMs = 60 * 60 * 1000; - for (int t = startTime; t < endTime; t += hourMs) { - double x = (t - startTime) * pixelPerMs; + final int totalHours = (endTime - startTime) ~/ hourMs; - DateTime dt = DateTime.fromMillisecondsSinceEpoch(t); - String label = t == startTime - ? DateFormat('HH:mm').format(dt) - : DateFormat('h').format(dt); // 12小时制 + // 1. 始终显示开始时间 + double x = 0; + DateTime startDt = DateTime.fromMillisecondsSinceEpoch(startTime); + String label = DateFormat('HH:mm').format(startDt); - textPainter.text = TextSpan( - text: label, - style: TextStyle(fontSize: 10, color: Colors.grey), - ); - textPainter.layout(); - textPainter.paint( - canvas, - Offset(x - textPainter.width / 2, height + 2), // 标签显示在底部 - ); + textPainter.text = TextSpan( + text: label, + style: TextStyle(fontSize: 10, color: Colors.grey), + ); + textPainter.layout(); + textPainter.paint( + canvas, + Offset(x - textPainter.width / 2, height + 2), + ); + + // 2. 决定显示策略 + if (totalHours <= 8) { + // 小时间段:显示所有整点小时 + for (int t = startTime + hourMs; t < endTime; t += hourMs) { + x = (t - startTime) * pixelPerMs; + DateTime dt = DateTime.fromMillisecondsSinceEpoch(t); + + // 判断是否接近边界(30分钟内不显示) + if (t - startTime < 30 * 60 * 1000 || endTime - t < 30 * 60 * 1000) { + continue; + } + + label = dt.hour == 0 ? "0" : "${dt.hour}"; + + textPainter.text = TextSpan( + text: label, + style: TextStyle(fontSize: 10, color: Colors.grey), + ); + textPainter.layout(); + textPainter.paint( + canvas, + Offset(x - textPainter.width / 2, height + 2), + ); + } + } else { + // 长时间段:使用自适应间隔 + int labelInterval = (totalHours / 6).ceil(); + + // 计算第一个标签位置(对齐整点) + int firstLabelMs = + ((startTime ~/ (labelInterval * hourMs))) * labelInterval * hourMs; + if (firstLabelMs <= startTime) { + firstLabelMs += labelInterval * hourMs; + } + + // 绘制中间标签 + for (int t = firstLabelMs; t < endTime; t += labelInterval * hourMs) { + // 跳过太接近边界的时间点(1小时内不显示) + if (t - startTime < hourMs || endTime - t < hourMs) continue; + + x = (t - startTime) * pixelPerMs; + DateTime dt = DateTime.fromMillisecondsSinceEpoch(t); + label = dt.hour == 0 ? "0" : "${dt.hour}"; + + textPainter.text = TextSpan( + text: label, + style: TextStyle(fontSize: 10, color: Colors.grey), + ); + textPainter.layout(); + textPainter.paint( + canvas, + Offset(x - textPainter.width / 2, height + 2), + ); + } } - // ✅ 画终点时间 - { - double x = (endTime - startTime) * pixelPerMs; - DateTime dt = DateTime.fromMillisecondsSinceEpoch(endTime); - String label = DateFormat('HH:mm').format(dt); + // 3. 始终显示结束时间 + x = (endTime - startTime) * pixelPerMs; + DateTime endDt = DateTime.fromMillisecondsSinceEpoch(endTime); + label = DateFormat('HH:mm').format(endDt); - textPainter.text = TextSpan( - text: label, - style: TextStyle(fontSize: 10, color: Colors.grey), - ); - textPainter.layout(); - textPainter.paint( - canvas, - Offset(x - textPainter.width / 2, height + 2), - ); - } + textPainter.text = TextSpan( + text: label, + style: TextStyle(fontSize: 10, color: Colors.grey), + ); + textPainter.layout(); + textPainter.paint( + canvas, + Offset(x - textPainter.width / 2, height + 2), + ); } @override diff --git a/lib/pages/sleep_report/component/SleepCard.dart b/lib/pages/sleep_report/component/SleepCard.dart index 9f36a5d..51df834 100644 --- a/lib/pages/sleep_report/component/SleepCard.dart +++ b/lib/pages/sleep_report/component/SleepCard.dart @@ -112,6 +112,7 @@ class _SleepCardState extends State with TickerProviderStateMixin { padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), child: Wrap( + alignment: WrapAlignment.center, spacing: 23.rpx, runSpacing: 25.rpx, children: List.generate(data.length, (index) { diff --git a/lib/pages/sleep_report/component/SleepScoreWidget.dart b/lib/pages/sleep_report/component/SleepScoreWidget.dart index d4257e4..5ca56fe 100644 --- a/lib/pages/sleep_report/component/SleepScoreWidget.dart +++ b/lib/pages/sleep_report/component/SleepScoreWidget.dart @@ -86,7 +86,7 @@ class _SleepScoreWidgetState extends State { child: Text( '30天平均分'.tr, style: TextStyle( - color: Color(0xFFD3D3D3), + color: themeController.currentColor.sc4, fontSize: 26.rpx, letterSpacing: 0.0, ), @@ -105,7 +105,7 @@ class _SleepScoreWidgetState extends State { letterSpacing: 0.0, ), ), - ].divide(SizedBox(height: 56.rpx)), + ].divide(SizedBox(height: 62.rpx)), ), Column( mainAxisSize: MainAxisSize.max, @@ -114,7 +114,7 @@ class _SleepScoreWidgetState extends State { Text( '睡眠等级'.tr, style: TextStyle( - color: Color(0xFFD3D3D3), + color: themeController.currentColor.sc4, fontSize: 26.rpx, letterSpacing: 0.0, ), @@ -132,7 +132,7 @@ class _SleepScoreWidgetState extends State { letterSpacing: 0.0, ), ), - ].divide(SizedBox(height: 56.rpx)), + ].divide(SizedBox(height: 62.rpx)), ), ], ), @@ -153,7 +153,8 @@ class _SleepScoreWidgetState extends State { child: Text( "睡眠评分".tr, style: TextStyle( - color: Colors.white, + color: themeController.currentColor.sc4, + // color: Colors.red, fontSize: AppConstants().normal_text_fontSize, ), diff --git a/lib/pages/sleep_report/new_sleep_report_page.dart b/lib/pages/sleep_report/new_sleep_report_page.dart index 75b5364..fc00bf5 100644 --- a/lib/pages/sleep_report/new_sleep_report_page.dart +++ b/lib/pages/sleep_report/new_sleep_report_page.dart @@ -112,60 +112,11 @@ class _NewSleepReportPageState extends State { Future.microtask(() { _initSleepReportData(); }); - // try { - // if (Get.isRegistered(tag: widget.data["tag"]) == - // false) { - // Get.put(tag: widget.data["tag"], SleepReportController()); - // } - // sleepReportController = Get.find(tag: widget.data["tag"]); - // // sleepReportController.sleepReport.value = {}; - // if (widget.data['date'] == null) { - // widget.data['date'] = DateTime.now(); - // } - // calendarController.selectedDate.value = - // DateTime.fromMillisecondsSinceEpoch(widget.data['date']); - // sleepReportController.selectedDate.value = - // DateTime.fromMillisecondsSinceEpoch(widget.data['date']); - // if (widget.data['type'] != null) { - // sleepReportController.model.type = widget.data['type']; - // } else { - // sleepReportController.model.type = 1; - // } - // String date = MyUtils.formatToDate(widget.data['date']); - // // String date = '2025-5-27'; - // sleepReportController.isLoading.value = true; - // requestWithLog( - // logTitle: "查询睡眠报告", - // method: MyHttpMethod.get, - // queryUrl: - // "https://sleepdata.he-info.com/api/analysis/sleep/analysis?mac=${widget.data['mac']}&time=${date}&type=${sleepReportController.model.type}", - // onSuccess: (res) { - // print(res); - // sleepReportController.isLoading.value = false; - // sleepReportController.sleepReport.value = res.data; - // sleepReportController.updateAll(); - // _scrollToTargetComponent(sleepReportController.sleepReport); - // }, - // onFailure: (res) { - // if (MainPageBBottomChange.getCurrentIndex() != null) { - // if (MainPageBBottomChange.getCurrentIndex() == 1) { - // TopSlideNotification.show(context, - // text: res.msg!, - // textColor: themeController.currentColor.sc9); - // } - // } else {} - // sleepReportController.sleepReport.value = {}; - // sleepReportController.isLoading.value = false; - // sleepReportController.updateAll(); - // print(res); - // }); - // } catch (e) { - // ef.log("$e"); - // } double lineWidth = 115.rpx; return LayoutBuilder( builder: (context, bodySize) => GestureDetector( + onHorizontalDragEnd: _handleHorizontalDrag, // 添加水平滑动检测 // onTap: () => FocusScope.of(context).unfocus(),, child: Container( decoration: BoxDecoration( @@ -1476,4 +1427,29 @@ class _NewSleepReportPageState extends State { ef.log("$e"); } } + + void _handleHorizontalDrag(DragEndDetails details) { + // 检测滑动手势 + if (details.primaryVelocity! > 0) { + // 向右滑动 - 切换到上一个报告类型 + _switchReportType(-1); + } else if (details.primaryVelocity! < 0) { + // 向左滑动 - 切换到下一个报告类型 + _switchReportType(1); + } + } + + void _switchReportType(int direction) { + int currentType = sleepReportController.model.type!; + int newType = currentType + direction; + + // 限制类型在1-3之间 + if (newType < 1) newType = 1; + if (newType > 3) newType = 3; + + // 只有当类型变化时才加载 + if (newType != currentType) { + loadSleepReport(newType); + } + } } diff --git a/lib/pages/user/setting_page.dart b/lib/pages/user/setting_page.dart index 9a41c79..913fd27 100644 --- a/lib/pages/user/setting_page.dart +++ b/lib/pages/user/setting_page.dart @@ -346,7 +346,9 @@ class _SettingPageState extends State { onTap: () { // TopSlideNotification.show(context, // text: "待开发功能".tr); - Get.toNamed("/userSchemePage"); + // Get.toNamed("/userSchemePage"); + Get.toNamed("/userPolicyPageNew", + arguments: getPrivacy(2)); }, child: Container( child: Padding( @@ -395,7 +397,9 @@ class _SettingPageState extends State { onTap: () { // TopSlideNotification.show(context, // text: "待开发功能".tr); - Get.toNamed("/privacyPage"); + // Get.toNamed("/privacyPage"); + Get.toNamed("/privacyPolicyPageNew", + arguments: getPrivacy(1)); }, child: Container( child: Padding( @@ -544,21 +548,21 @@ class _SettingPageState extends State { ), Padding( padding: EdgeInsetsDirectional.fromSTEB( - 0.rpx, 100.rpx, 0.rpx, 0), + 0.rpx, 50.rpx, 0.rpx, 100.rpx), child: ClickableContainer( borderRadius: AppConstants().button_container_radius, // 圆角半径 onTap: () {}, backgroundColor: Colors.transparent, // 渐变色是同一个色,也可以根据需要调整 - highlightColor: themeController.currentColor.sc5, + highlightColor: Colors.transparent, padding: EdgeInsetsDirectional.fromSTEB( 0.rpx, 0.rpx, 0.rpx, 0), child: Container( width: // MediaQuery.sizeOf(context).width * 0.66, bodySize.maxWidth, - height: MediaQuery.sizeOf(context).height * 0.055, + // height: MediaQuery.sizeOf(context).height * 0.055, constraints: BoxConstraints( minWidth: 500.rpx, minHeight: 90.rpx, @@ -568,7 +572,7 @@ class _SettingPageState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'ICP备案号:皖ICP备2024068219号-1A'.tr, + 'icp备案号'.tr, style: TextStyle( color: themeController.currentColor.sc4, fontFamily: 'Inter', @@ -579,9 +583,9 @@ class _SettingPageState extends State { ), Text( AppConstants().ent_type == 1 - ? 'Copyright © 2022-2025 嘉兴太和信息技术有限责任公司 版权所有' - .tr - : "Copyright © 2019-2029 合肥眠花糖家具有限责任公司 版权所有", + ? '公司信息'.tr.tr + : "Copyright © 2019-2029 合肥眠花糖家具有限责任公司 版权所有" + .tr, style: TextStyle( color: themeController.currentColor.sc4, fontFamily: 'Inter',