This commit is contained in:
wyf
2025-11-14 12:01:07 +08:00
parent 776275aa3d
commit 7e44998240
24 changed files with 409 additions and 187 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
assets/img/avatar1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

View File

@@ -549,6 +549,8 @@
"设备已被用户解绑,将取消当前分享!": "The device has been unbound by the user, and the current sharing will be cancelled.", "设备已被用户解绑,将取消当前分享!": "The device has been unbound by the user, and the current sharing will be cancelled.",
"消息列表": "message list", "消息列表": "message list",
"睡眠报告提示": "This page is not a medical standard, and the data is for reference only.", "睡眠报告提示": "This page is not a medical standard, and the data is for reference only.",
"MAC号": "MAC Address" "MAC号": "MAC Address",
"微信用户": "WeChat User",
"其他设备正在绑定中,是否终止其他设备绑定?": "Another device is binding. Terminate?",
"未配置网络提示": "Network Not Configured"
} }

View File

@@ -551,6 +551,8 @@
"去查看": "去查看", "去查看": "去查看",
"设备已被用户解绑,将取消当前分享!": "设备已被用户解绑,将取消当前分享!", "设备已被用户解绑,将取消当前分享!": "设备已被用户解绑,将取消当前分享!",
"消息列表": "消息列表", "消息列表": "消息列表",
"睡眠报告提示":"本页内容非医疗标准,数据仅供参考", "睡眠报告提示": "本页内容非医疗标准,数据仅供参考",
"MAC号": "MAC号" "MAC号": "MAC号",
"微信用户": "微信用户",
"其他设备正在绑定中,是否终止其他设备绑定?": "其他设备正在绑定中,是否终止其他设备绑定?"
} }

View File

@@ -545,6 +545,9 @@
"去查看": "去查看", "去查看": "去查看",
"设备已被用户解绑,将取消当前分享!": "設備已被用戶解綁,將取消當前分享!", "设备已被用户解绑,将取消当前分享!": "設備已被用戶解綁,將取消當前分享!",
"消息列表": "消息列表", "消息列表": "消息列表",
"睡眠报告提示":"本頁內容非醫療標準,數據僅供參考", "睡眠报告提示": "本頁內容非醫療標準,數據僅供參考",
"MAC号": "MAC號" "MAC号": "MAC號",
"微信用户": "微信用戶",
"其他设备正在绑定中,是否终止其他设备绑定?": "其他設備正在綁定中,是否終止其他設備綁定?",
"未配置网络提示": "當前設備未進行網路配置,是否確認跳過網路配置?"
} }

View File

@@ -0,0 +1,23 @@
import 'dart:async';
class EventBus {
static final EventBus _instance = EventBus._internal();
factory EventBus() => _instance;
EventBus._internal();
final _controller = StreamController.broadcast();
// 发出任意事件
void emit(event) {
_controller.add(event);
}
// 监听指定类型的事件
Stream<T> on<T>() {
return _controller.stream.where((event) => event is T).cast<T>();
}
void dispose() {
_controller.close();
}
}

View File

@@ -0,0 +1,14 @@
class VideoDownloadEvent {
final bool success;
VideoDownloadEvent(this.success);
}
class BleConnectEvent {
final bool connected;
BleConnectEvent(this.connected);
}
class SwitchLanguageEvent {
final String language;
SwitchLanguageEvent(this.language);
}

View File

@@ -9,7 +9,9 @@ import 'package:vbvs_app/component/home_page/SleepDataModuleWidget.dart';
import 'package:vbvs_app/component/home_page/SleepDateWidget.dart'; import 'package:vbvs_app/component/home_page/SleepDateWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/enum/DataStatus.dart';
class DynamicReportDetailWidget extends StatefulWidget { class DynamicReportDetailWidget extends StatefulWidget {
final List<SleepDateWidget> sleepDateWidgets; final List<SleepDateWidget> sleepDateWidgets;
@@ -32,6 +34,7 @@ class _DynamicReportDetailWidgetState extends State<DynamicReportDetailWidget> {
final ThemeController themeController = Get.find(); final ThemeController themeController = Get.find();
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
bool _hasScrolled = false; bool _hasScrolled = false;
BodyDeviceController bodyDeviceController = Get.find();
@override @override
void initState() { void initState() {
@@ -74,8 +77,7 @@ class _DynamicReportDetailWidgetState extends State<DynamicReportDetailWidget> {
SizedBox(height: 33.rpx), SizedBox(height: 33.rpx),
_buildSleepDateWidgets(), _buildSleepDateWidgets(),
SizedBox(height: 20.rpx), SizedBox(height: 20.rpx),
if (!AppConstants.is_test_account) if (!AppConstants.is_test_account) _buildSleepDataModuleWidgets(),
_buildSleepDataModuleWidgets(),
], ],
), ),
), ),
@@ -95,13 +97,20 @@ class _DynamicReportDetailWidgetState extends State<DynamicReportDetailWidget> {
onTap: () async { onTap: () async {
await Get.toNamed("/bodyDevice", arguments: targetDevice); await Get.toNamed("/bodyDevice", arguments: targetDevice);
}, },
child: Text( child: Container(
'${targetDevice['person']?['name'] == null ? '未命名'.tr : targetDevice['person']['name']}', constraints: BoxConstraints(
style: TextStyle( maxWidth: MediaQuery.sizeOf(context).width * 0.6,
fontFamily: 'Inter', ),
fontSize: 30.rpx, child: Text(
letterSpacing: 0.0, '${targetDevice['person']?['name'] == null ? '未命名'.tr : targetDevice['person']['name']}',
color: themeController.currentColor.sc3, style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
), ),
), ),
), ),
@@ -183,6 +192,18 @@ class _DynamicReportDetailWidgetState extends State<DynamicReportDetailWidget> {
} }
Widget _buildSleepDataModuleWidgets() { Widget _buildSleepDataModuleWidgets() {
// homePageSleepFlag
//widget.targetDevice['mac']
if (bodyDeviceController.homePageSleepFlag[widget.targetDevice['mac']] ==
DataStatus.Loading.code) {
return Container(
height: 200.rpx,
alignment: Alignment.center,
child: CircularProgressIndicator(
color: themeController.currentColor.sc1,
),
);
}
if (widget.sleepDataModuleWidgets.isEmpty) { if (widget.sleepDataModuleWidgets.isEmpty) {
return Container( return Container(
height: 200.rpx, height: 200.rpx,
@@ -207,16 +228,34 @@ class _DynamicReportDetailWidgetState extends State<DynamicReportDetailWidget> {
// ); // );
// } // }
// return Container(
// width: double.infinity,
// height: 200.rpx,
// child: SingleChildScrollView(
// scrollDirection: Axis.horizontal,
// child: Row(
// children: widget.sleepDataModuleWidgets
// .map((widget) => widget)
// .toList()
// .divide(SizedBox(width: 14.rpx)),
// ),
// ),
// );
var aa = widget.sleepDataModuleWidgets
// 过滤:当 data 中存在 'show' 且其为 false 时排除该元素
.where((item) => item.data?['show'] != false)
// 保持元素本身SleepDataModuleWidget
.map((item) => item)
.toList();
return Container( return Container(
width: double.infinity, width: double.infinity,
height: 200.rpx, height: 200.rpx,
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: Row( child: Row(
children: widget.sleepDataModuleWidgets children:
.map((widget) => widget) // 保留你原来的 divide 间隔处理
.toList() aa.divide(SizedBox(width: 14.rpx)),
.divide(SizedBox(width: 14.rpx)),
), ),
), ),
); );

View File

@@ -11,6 +11,7 @@ import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/enum/APPPackageType.dart';
import 'package:vbvs_app/enum/DataStatus.dart';
import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/model/api_response.dart';
part 'body_device_controller.g.dart'; // 由json_serializable自动生成的部分 part 'body_device_controller.g.dart'; // 由json_serializable自动生成的部分
@@ -51,6 +52,8 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
Timer? _sleepReportTimer; // 定时器 Timer? _sleepReportTimer; // 定时器
RxMap homePageSleepFlag = {}.obs; //正在请求睡眠报告数据
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@@ -220,6 +223,7 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
try { try {
ef.log("刷新睡眠报告"); ef.log("刷新睡眠报告");
sleepReportData.value = {}; sleepReportData.value = {};
homePageSleepFlag = {}.obs;
ApiResponse<Map<String, List<dynamic>>> apiResponse = ApiResponse( ApiResponse<Map<String, List<dynamic>>> apiResponse = ApiResponse(
code: -1, code: -1,
msg: "请求失败".tr, msg: "请求失败".tr,
@@ -241,7 +245,7 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
if (mac.isEmpty) continue; if (mac.isEmpty) continue;
sleepReportData[mac] = []; // 初始化当前设备的数据列表 sleepReportData[mac] = []; // 初始化当前设备的数据列表
homePageSleepFlag[mac] = DataStatus.Loading.code;
String queryUrl = String queryUrl =
"$serviceAddress$serviceName$serviceApi?mac=$mac&time=${DateTime.now().millisecondsSinceEpoch}&sleepType=1"; "$serviceAddress$serviceName$serviceApi?mac=$mac&time=${DateTime.now().millisecondsSinceEpoch}&sleepType=1";
try { try {
@@ -258,6 +262,7 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
} }
var response = await EasyDartModule.dio.get(queryUrl); var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) { if (response != null) {
homePageSleepFlag[mac] = DataStatus.success.code;
var responseData = response.data is String var responseData = response.data is String
? jsonDecode(response.data) ? jsonDecode(response.data)
: response.data; : response.data;
@@ -276,6 +281,7 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
} }
} catch (e) { } catch (e) {
EasyDartModule.logger.warning("请求设备 $mac 的睡眠数据失败: $e"); EasyDartModule.logger.warning("请求设备 $mac 的睡眠数据失败: $e");
homePageSleepFlag[mac] = DataStatus.Fail.code;
} }
} }
if (sleepReportData.value.isNotEmpty) { if (sleepReportData.value.isNotEmpty) {

View File

@@ -152,7 +152,8 @@ class PersonController extends GetControllerEx<PersonModel> {
} }
} }
if (name.value.isEmpty) { if (name.value.isEmpty) {
apiResponse.msg = "请输入姓名".tr; // apiResponse.msg = "请输入姓名".tr;
apiResponse.code = 1;
return apiResponse; return apiResponse;
} }
if (person == null) { if (person == null) {

View File

@@ -455,18 +455,19 @@ class WeatherModelController extends GetControllerEx<WeatherModel> {
Future<void> onInit() async { Future<void> onInit() async {
super.onInit(); super.onInit();
try { //去掉天气
await getCurrentLocation(); // try {
_weatherTimer = Timer.periodic(Duration(minutes: 10), (timer) { // await getCurrentLocation();
getCurrentWeather(); // 每 60 秒更新一次天气 // _weatherTimer = Timer.periodic(Duration(minutes: 10), (timer) {
}); // getCurrentWeather(); // 每 60 秒更新一次天气
// });
_locationTimer = Timer.periodic(Duration(minutes: 10), (timer) { // _locationTimer = Timer.periodic(Duration(minutes: 10), (timer) {
getCurrentLocation(); // 每 10 分钟更新一次位置 // getCurrentLocation(); // 每 10 分钟更新一次位置
}); // });
} catch (e) { // } catch (e) {
ef.log("[天气和定位请求失败]"); // ef.log("[天气和定位请求失败]");
} // }
} }
@override @override

10
lib/enum/DataStatus.dart Normal file
View File

@@ -0,0 +1,10 @@
enum DataStatus {
Loading(1, '加载中'),
Fail(2, '失败'),
success(3, '成功');
final int code;
final String description;
const DataStatus(this.code, this.description);
}

View File

@@ -274,7 +274,8 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
), ),
]; ];
if (widget.device['bind_type'] == BindType.active.code && !AppConstants.is_test_account) { if (widget.device['bind_type'] == BindType.active.code &&
!AppConstants.is_test_account) {
items.addAll([ items.addAll([
_buildMenuItem( _buildMenuItem(
text: "WIFI配置".tr, text: "WIFI配置".tr,
@@ -413,12 +414,17 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
alignment: AlignmentDirectional(-1, 0), alignment: AlignmentDirectional(-1, 0),
child: TextFormField( child: TextFormField(
onChanged: (value) { onChanged: (value) {
personController.name.value = value; if (value == null || value.isEmpty) {
personController.name.value = "体征监测设备".tr;
} else {
personController.name.value = value;
}
}, },
autofocus: false, autofocus: false,
decoration: InputDecoration( decoration: InputDecoration(
isDense: true, isDense: true,
hintText: '请输入人员名称'.tr, // hintText: '请输入人员名称'.tr,
hintText: "体征监测设备".tr,
hintStyle: TextStyle( hintStyle: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: 26.rpx, fontSize: 26.rpx,
@@ -447,6 +453,10 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
color: Colors.black, color: Colors.black,
), ),
cursorColor: Colors.white, cursorColor: Colors.white,
initialValue: widget.device['person']['name'] == null ||
widget.device['person']['name'] == ""
? "体征监测设备".tr
: widget.device['person']['name'],
), ),
), ),
), ),
@@ -521,14 +531,21 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Container(
// 'TH689564522DL', constraints: BoxConstraints(
'${widget.device['person']?['name'] ?? '未命名'.tr}', // maxWidth: MediaQuery.sizeOf(context).width - 200.rpx,
style: TextStyle( maxWidth: MediaQuery.sizeOf(context).width * 0.6,
fontFamily: 'Inter', ),
fontSize: 30.rpx, child: Text(
letterSpacing: 0.0, '${widget.device['person']?['name'] ?? '未命名'.tr}',
color: themeController.currentColor.sc3, style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
), ),
), ),
// ClickableContainer( // ClickableContainer(
@@ -1347,7 +1364,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
// ), // ),
// ), // ),
// ), // ),
// SizedBox( // SizedBox(
// width: 20.rpx, // width: 20.rpx,
// ), // ),

View File

@@ -695,7 +695,7 @@ void showSingleConfirmDialog(
// padding: // padding:
// EdgeInsetsDirectional.fromSTEB(0, 33.rpx, 0, 0.rpx), // EdgeInsetsDirectional.fromSTEB(0, 33.rpx, 0, 0.rpx),
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
33.rpx, 33.rpx, 33.rpx, 33.rpx), 33.rpx, 64.rpx, 33.rpx, 33.rpx),
child: SvgPicture.asset( child: SvgPicture.asset(
'assets/img/icon/close.svg', 'assets/img/icon/close.svg',
width: 25.rpx, width: 25.rpx,
@@ -710,7 +710,7 @@ void showSingleConfirmDialog(
alignment: AlignmentDirectional(0, 0), alignment: AlignmentDirectional(0, 0),
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
33.rpx, 60.rpx, 33.rpx, 33.rpx), 33.rpx, 33.rpx, 33.rpx, 33.rpx),
child: Text( child: Text(
title, title,
style: TextStyle( style: TextStyle(
@@ -1793,7 +1793,7 @@ void showConfirmCancelDialog(
String confirmText = "", // ✅ 确认按钮文字 String confirmText = "", // ✅ 确认按钮文字
String cancelText = "", // ✅ 取消按钮文字 String cancelText = "", // ✅ 取消按钮文字
Color? confirmButtonColor, // ✅ 新增:确认按钮背景色 Color? confirmButtonColor, // ✅ 新增:确认按钮背景色
Color? cancelButtonColor, // ✅ 新增:取消按钮背景色 Color? cancelButtonColor, // ✅ 新增:取消按钮背景色
}) { }) {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
try { try {

View File

@@ -33,7 +33,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
Timer? _pollingTimer; Timer? _pollingTimer;
bool exit = false; bool exit = false;
bool start = false; bool start = false;//是否开始进行校准
@override @override
void initState() { void initState() {
super.initState(); super.initState();

View File

@@ -572,7 +572,7 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
color: themeController color: themeController
.currentColor.sc2, .currentColor.sc2,
fontSize: AppConstants() fontSize: AppConstants()
.title_text_fontSize, .middler_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
@@ -597,9 +597,10 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
onTap: () async { onTap: () async {
try { try {
DailyLogUtils.writeLog("点击登录"); DailyLogUtils.writeLog("点击登录");
bool agree = if (loginController.model.register_agree ==
loginController.model.register_agree!; null ||
if (!agree) { loginController.model.register_agree! ==
false) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "登录页.未同意协议".tr, text: "登录页.未同意协议".tr,
@@ -922,7 +923,7 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Obx(() { Obx(() {
var aa = var aa =
loginController.model.isWeChatNotInstalled; loginController.model.isWeChatNotInstalled;

View File

@@ -112,7 +112,8 @@ class _MessageWidgetWidgetState extends State<MessageWidgetWidget> {
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2 themeController.currentColor.sc2
] ]
: [themeController.currentColor.sc4], // 单色背景 // : [themeController.currentColor.sc4], // 单色背景
: [Colors.grey.withOpacity(0.2)], // 单色背景
enableAnimation: true, // 有点击缩放动画 enableAnimation: true, // 有点击缩放动画
enableGradient: false, // 不用渐变 enableGradient: false, // 不用渐变
onTap: () { onTap: () {
@@ -148,7 +149,9 @@ class _MessageWidgetWidgetState extends State<MessageWidgetWidget> {
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: 26.rpx, fontSize: 26.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
color: Colors.white, color: messageInfo['status'] == 1
? Colors.white
: Colors.grey,
), ),
), ),
), ),

View File

@@ -18,7 +18,6 @@ import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.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/device/body_device_controller.dart';
import 'package:vbvs_app/controller/home/home_controller.dart'; import 'package:vbvs_app/controller/home/home_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/person/person_controller.dart'; import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
@@ -222,7 +221,7 @@ class _HomePageState extends State<HomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
weatherModelController.getCurrentWeather(); // weatherModelController.getCurrentWeather();
return LayoutBuilder( return LayoutBuilder(
builder: (context, bodySize) => GestureDetector( builder: (context, bodySize) => GestureDetector(
onTap: () { onTap: () {
@@ -320,77 +319,86 @@ class _HomePageState extends State<HomePage> {
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.end, MainAxisAlignment.end,
children: [ children: [
Text( Container(
userInfoController.model.user! constraints: BoxConstraints(
.nick_name ?? maxWidth:
'未命名'.tr, bodySize.maxWidth *
style: TextStyle( 0.6),
color: themeController child: Text(
.currentColor.sc3, userInfoController.model.user!
fontSize: AppConstants() .nick_name ??
.normal_text_fontSize, '未命名'.tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
maxLines: 1,
overflow:
TextOverflow.ellipsis,
), ),
), ),
Obx(() { // Obx(() {
return Row( // return Row(
children: [ // children: [
Text( // Text(
"${weatherModelController.model.cityName ?? '未知数据'.tr}", // "${weatherModelController.model.cityName ?? '未知数据'.tr}",
style: TextStyle( // style: TextStyle(
color: themeController // color: themeController
.currentColor.sc4, // .currentColor.sc4,
fontSize: AppConstants() // fontSize: AppConstants()
.normal_text_fontSize, // .normal_text_fontSize,
), // ),
), // ),
Text( // Text(
"${(weatherModelController.model.current_temperature != null && weatherModelController.model.current_temperature! > 0) ? weatherModelController.model.current_temperature : '未知数据'.tr}" + // "${(weatherModelController.model.current_temperature != null && weatherModelController.model.current_temperature! > 0) ? weatherModelController.model.current_temperature : '未知数据'.tr}" +
"°C", // "°C",
style: TextStyle( // style: TextStyle(
color: themeController // color: themeController
.currentColor.sc4, // .currentColor.sc4,
fontSize: AppConstants() // fontSize: AppConstants()
.normal_text_fontSize, // .normal_text_fontSize,
), // ),
), // ),
Text( // Text(
"${(weatherModelController.model.weather_info?.isNotEmpty ?? false) ? weatherModelController.model.weather_info : '未知数据'.tr}", // "${(weatherModelController.model.weather_info?.isNotEmpty ?? false) ? weatherModelController.model.weather_info : '未知数据'.tr}",
style: TextStyle( // style: TextStyle(
color: themeController // color: themeController
.currentColor.sc4, // .currentColor.sc4,
fontSize: AppConstants() // fontSize: AppConstants()
.normal_text_fontSize, // .normal_text_fontSize,
), // ),
), // ),
if (weatherModelController // if (weatherModelController
.model // .model
.weatherIconurl != // .weatherIconurl !=
null && // null &&
weatherModelController // weatherModelController
.model // .model
.weatherIconurl! // .weatherIconurl!
.isNotEmpty) // .isNotEmpty)
Container( // Container(
width: 35.rpx, // width: 35.rpx,
height: 26.rpx, // height: 26.rpx,
clipBehavior: // clipBehavior:
Clip.antiAlias, // Clip.antiAlias,
decoration: // decoration:
BoxDecoration( // BoxDecoration(
shape: BoxShape // shape: BoxShape
.circle), // .circle),
child: SvgPicture.asset( // child: SvgPicture.asset(
"assets/images/weather/${weatherModelController.model.weatherIconurl}-fill.svg", // "assets/images/weather/${weatherModelController.model.weatherIconurl}-fill.svg",
// fit: BoxFit.cover, // // fit: BoxFit.cover,
color: themeController // color: themeController
.currentColor.sc4, // .currentColor.sc4,
), // ),
), // ),
].divide(SizedBox( // ].divide(SizedBox(
width: 20.rpx, // width: 20.rpx,
)), // )),
); // );
}), // }),
], ],
), ),
); );
@@ -1066,6 +1074,7 @@ class _HomePageState extends State<HomePage> {
}) })
: [], : [],
), ),
SizedBox( SizedBox(
height: height:
26.rpx), // 每个 widget 下方间距(包括最后一个) 26.rpx), // 每个 widget 下方间距(包括最后一个)

View File

@@ -1,9 +1,13 @@
import 'dart:async';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/EventBus.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/eventType.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart'; import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
@@ -29,6 +33,13 @@ class _MessagePageState extends State<MessagePage> {
_pageController = _pageController =
PageController(initialPage: messageController.model.type == 1 ? 0 : 1); PageController(initialPage: messageController.model.type == 1 ? 0 : 1);
messageController.getMessageStatus(); messageController.getMessageStatus();
late StreamSubscription<SwitchLanguageEvent> subscription;
// 监听切换语言
subscription = EventBus().on<SwitchLanguageEvent>().listen((event) {
ef.log("切换语言事件通知");
_fetchMessageData();
});
_fetchMessageData(); _fetchMessageData();
} }

View File

@@ -87,7 +87,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
.map((e) => (e['_id']) as String) .map((e) => (e['_id']) as String)
.toList(); .toList();
repairController.deviceListIdLabel = bodyDeviceController.deviceList repairController.deviceListIdLabel = bodyDeviceController.deviceList
.map((e) => (e['code']??e['mac']) as String) .map((e) => (e['code'] ?? e['mac']) as String)
.toList(); .toList();
} }
return LayoutBuilder( return LayoutBuilder(
@@ -197,28 +197,32 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
themeController.currentColor.sc2, themeController.currentColor.sc2,
] ]
: [themeController.currentColor.sc5], : [themeController.currentColor.sc5],
child: Container( child: Padding(
width: (MediaQuery.sizeOf(context).width * padding: EdgeInsets.fromLTRB(
0.284) 32.rpx, 0, 32.rpx, 0),
.rpx, child: Container(
constraints: BoxConstraints( // width: (MediaQuery.sizeOf(context).width *
minWidth: 213.rpx, // 0.284)
minHeight: 91.rpx, // .rpx,
), constraints: BoxConstraints(
decoration: BoxDecoration( // minWidth: 213.rpx,
borderRadius: minHeight: 91.rpx,
BorderRadius.circular(20.rpx), ),
), decoration: BoxDecoration(
child: Align( borderRadius:
alignment: AlignmentDirectional(0, 0), BorderRadius.circular(20.rpx),
child: Text( ),
deviceType['name'], child: Align(
style: TextStyle( alignment: AlignmentDirectional(0, 0),
letterSpacing: 0.0, child: Text(
color: themeController deviceType['name'],
.currentColor.sc3, style: TextStyle(
fontSize: AppConstants() letterSpacing: 0.0,
.normal_text_fontSize, color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
), ),
), ),
), ),

View File

@@ -265,34 +265,108 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
].divide(SizedBox(width: 24.rpx)), ].divide(SizedBox(width: 24.rpx)),
), ),
), ),
// Container(
// width: double.infinity,
// // height: 151.rpx,
// height: 200.rpx,
// decoration: BoxDecoration(
// color: themeController.currentColor.sc15,
// borderRadius: BorderRadius.circular(20.rpx),
// ),
// child: Container(
// width: 200.rpx,
// child: TextFormField(
// controller: repairController.onReDraw(
// TextEditingController(text: widget.model['issue']),
// (textEditingController) {
// textEditingController.text = widget.model['issue'];
// }),
// onChanged: (value) {
// widget.model['issue'] = value;
// },
// maxLines: null, // 👈 支持无限行
// // controller: TextEditingController(),
// autofocus: false,
// obscureText: false,
// maxLength: 60,
// decoration: InputDecoration(
// isDense: true,
// labelStyle: TextStyle(
// letterSpacing: 0.0,
// ),
// hintText: '问题描述'.tr,
// hintStyle: TextStyle(
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// color: themeController.currentColor.sc4,
// ),
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color: Color(0x00000000),
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8.rpx),
// ),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color: Color(0x00000000),
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8.rpx),
// ),
// errorBorder: OutlineInputBorder(
// borderSide: BorderSide(
// //
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8.rpx),
// ),
// focusedErrorBorder: OutlineInputBorder(
// borderSide: BorderSide(
// //
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8.rpx),
// ),
// filled: false,
// contentPadding: EdgeInsets.symmetric(
// vertical: 20.rpx, horizontal: 20.rpx),
// ),
// style: TextStyle(
// color: themeController.currentColor.sc3,
// fontSize: AppConstants().normal_text_fontSize,
// ),
// cursorColor: themeController.currentColor.sc3,
// ),
// ),
// ),
Container( Container(
width: double.infinity, width: double.infinity,
height: 151.rpx, height: 170.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
color: themeController.currentColor.sc15, color: themeController.currentColor.sc15,
borderRadius: BorderRadius.circular(20.rpx), borderRadius: BorderRadius.circular(20.rpx),
), ),
child: Container( child: Padding(
width: 200.rpx, // 👇 给输入框整体加点内边距
padding: EdgeInsets.only(bottom: 10.rpx, right: 10.rpx),
child: TextFormField( child: TextFormField(
controller: repairController.onReDraw( controller: repairController.onReDraw(
TextEditingController(text: widget.model['issue']), TextEditingController(text: widget.model['issue']),
(textEditingController) { (textEditingController) {
textEditingController.text = widget.model['issue']; textEditingController.text = widget.model['issue'];
}), },
),
onChanged: (value) { onChanged: (value) {
widget.model['issue'] = value; widget.model['issue'] = value;
}, },
maxLines: null, // 👈 支持无限行 maxLines: null,
// controller: TextEditingController(),
autofocus: false, autofocus: false,
obscureText: false, obscureText: false,
maxLength: 60, maxLength: 60,
decoration: InputDecoration( decoration: InputDecoration(
isDense: true, isDense: true,
labelStyle: TextStyle(
letterSpacing: 0.0,
),
hintText: '问题描述'.tr, hintText: '问题描述'.tr,
hintStyle: TextStyle( hintStyle: TextStyle(
fontSize: 26.rpx, fontSize: 26.rpx,
@@ -300,36 +374,28 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
color: themeController.currentColor.sc4, color: themeController.currentColor.sc4,
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide:
color: Color(0x00000000), BorderSide(color: Colors.transparent, width: 1),
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx), borderRadius: BorderRadius.circular(8.rpx),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide:
color: Color(0x00000000), BorderSide(color: Colors.transparent, width: 1),
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
//
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
//
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx), borderRadius: BorderRadius.circular(8.rpx),
), ),
filled: false, filled: false,
contentPadding: EdgeInsets.symmetric(
vertical: 20.rpx, horizontal: 20.rpx), // 👇 调整输入区域与计数器的间距
contentPadding:
EdgeInsets.fromLTRB(20.rpx, 20.rpx, 20.rpx, 40.rpx),
// 👇 调整计数器样式和位置(上浮一点,不贴边)
counterStyle: TextStyle(
height: 1.2, // 控制计数器与下边的距离
fontSize: 22.rpx,
color: themeController.currentColor.sc4,
),
alignLabelWithHint: true,
), ),
style: TextStyle( style: TextStyle(
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
@@ -339,6 +405,7 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
), ),
), ),
), ),
ClickableContainer( ClickableContainer(
backgroundColor: themeController.currentColor.sc15, backgroundColor: themeController.currentColor.sc15,
highlightColor: themeController.currentColor.sc21, highlightColor: themeController.currentColor.sc21,

View File

@@ -2,8 +2,10 @@ import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/EventBus.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/eventType.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart'; import 'package:vbvs_app/controller/device/body_device_controller.dart';
@@ -125,6 +127,9 @@ class _LanguageSettingState extends State<LanguageSetting> {
languageController languageController
.selectLanguage .selectLanguage
.value = language; .value = language;
EventBus().emit(
SwitchLanguageEvent(
language.language_code));
await AppLanguage() await AppLanguage()
.loadLanguage(language .loadLanguage(language
.language_code); // 加载语言 .language_code); // 加载语言

View File

@@ -53,7 +53,7 @@ Widget DailyDataWidget(
sleepReport: sleepReport, sleepReport: sleepReport,
highlightItem: data['itemName'], highlightItem: data['itemName'],
), ),
SnoreViewWidgetWidget(sleepReport: sleepReport), // SnoreViewWidgetWidget(sleepReport: sleepReport),
BreathePauseNewWidget(sleepReport: sleepReport), BreathePauseNewWidget(sleepReport: sleepReport),
HeartHealthWidget(sleepReport: sleepReport), HeartHealthWidget(sleepReport: sleepReport),
DiseasePercentsWidget(sleepReport: sleepReport), DiseasePercentsWidget(sleepReport: sleepReport),

View File

@@ -99,7 +99,10 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
} }
} }
int num = AppLanguage().isChinese() ? 3 : 2; int num = AppLanguage().isChinese() ? 3 : 2;
List data = widget.sleepReport['bs'] ?? []; // List data = widget.sleepReport['bs'] ?? [];
List data = (widget.sleepReport['bs'] ?? [])
.where((item) => item['show'] != false)
.toList();
return Container( return Container(
width: double.infinity, width: double.infinity,