This commit is contained in:
wyf
2025-05-15 13:57:42 +08:00
parent fb5c3864a3
commit 75ddfca402
51 changed files with 2451 additions and 1233 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
assets/img/errorImg.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -347,8 +347,11 @@
"设备类型":"设备类型", "设备类型":"设备类型",
"发生时间":"发生时间", "发生时间":"发生时间",
"最小信号强度":"最小信号强度", "最小信号强度":"最小信号强度",
"匹配出的外围设备":"发生时间", "匹配出的外围设备":"匹配出的外围设备",
"连接中...": "连接中", "连接中...": "连接中",
"刷新":"刷新", "刷新":"刷新",
"版本":"版本:" "版本":"版本:",
"日报":"日报",
"月报":"月报",
"周报":"周报"
} }

View File

@@ -20,8 +20,8 @@ class ServiceConstant {
static String device_show = "/api/device/bind";//更新设备绑定 static String device_show = "/api/device/bind";//更新设备绑定
static String disease_list = "/api/personnel/disease/list";//获取疾病类型 static String disease_list = "/api/personnel/disease/list";//获取疾病类型
static String share_deleted = "";//删除分享 static String share_deleted = "";//删除分享
static String start_calibration = "";//开始校准 static String start_calibration = "/api/caibration";//开始校准
static String calibration_process = "";//校准进度 static String calibration_process = "/api/caibration";//校准进度
static String submit_repair = "";//提交报修 static String submit_repair = "";//提交报修

View File

@@ -25,6 +25,7 @@ class AppConstants {
double title_text_fontSize = 30.rpx; //标题文字字号 double title_text_fontSize = 30.rpx; //标题文字字号
double dropdown_height = 90.rpx; //标题文字字号 double dropdown_height = 90.rpx; //标题文字字号
double border_width = 1.rpx; //标题文字字号//border宽度
} }

View File

@@ -162,6 +162,17 @@ class MyUtils {
String twoDigits(int n) => n.toString().padLeft(2, '0'); String twoDigits(int n) => n.toString().padLeft(2, '0');
return '${twoDigits(date.month)}/${twoDigits(date.day)}'; return '${twoDigits(date.month)}/${twoDigits(date.day)}';
} }
static String getFormatChineseTime(date) {
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(date);
// 格式化年月日
String dateStr = DateFormat('yyyy年MM月dd日').format(dateTime);
// 获取星期
const weekDays = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
String weekStr = weekDays[dateTime.weekday - 1];
return '$dateStr $weekStr';
}
} }
Color stringToColor(String hexColor) { Color stringToColor(String hexColor) {
@@ -323,7 +334,6 @@ String time_08_Formatter_pattern(String time, String pattern) {
return DateFormat(pattern).format(DateTime.parse(time).toLocal()); return DateFormat(pattern).format(DateTime.parse(time).toLocal());
} }
enum LoadingDialogIcon { ble, wifi, none } enum LoadingDialogIcon { ble, wifi, none }
class LoadingDialog { class LoadingDialog {

View File

@@ -63,7 +63,8 @@ Future<ApiResponse> requestWithLog({
final responseData = final responseData =
response.data is String ? jsonDecode(response.data) : response.data; response.data is String ? jsonDecode(response.data) : response.data;
apiResponse = ApiResponse.fromJson(responseData, (object) => object); apiResponse = ApiResponse.fromJson(responseData, (object) => object,
rawResponse: response);
if (apiResponse.code == HttpStatusCodes.ok) { if (apiResponse.code == HttpStatusCodes.ok) {
MyUtils.formatResponse(apiResponse, successMsg, errorMsg); MyUtils.formatResponse(apiResponse, successMsg, errorMsg);

View File

@@ -1,113 +1,53 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.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'; // 假设你自己扩展的 .rpx import 'package:vbvs_app/common/util/MyUtils.dart';
import 'SleepdateWidget.dart'; // 导入你自定义的 SleepdateWidget import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/date/CalendarController.dart';
import 'SleepdateWidget.dart';
class SleepCalendarWidget extends StatefulWidget { class SleepCalendarWidget extends StatefulWidget {
final int? timestamp; // 可选时间戳 final int? timestamp;
final ValueChanged<DateTime>? onDateSelected;
const SleepCalendarWidget({super.key, this.timestamp}); const SleepCalendarWidget({
super.key,
this.timestamp,
this.onDateSelected,
});
@override @override
State<SleepCalendarWidget> createState() => _SleepCalendarWidgetState(); State<SleepCalendarWidget> createState() => _SleepCalendarWidgetState();
} }
class _SleepCalendarWidgetState extends State<SleepCalendarWidget> { class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
late DateTime _currentDate; CalendarController calendarController = Get.find();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_currentDate = widget.timestamp != null final initialDate = widget.timestamp != null
? DateTime.fromMillisecondsSinceEpoch(widget.timestamp!) ? DateTime.fromMillisecondsSinceEpoch(widget.timestamp!)
: DateTime.now(); : DateTime.now();
} calendarController.displayedMonth.value = initialDate;
calendarController.selectedDate.value = initialDate;
List<DateTime> getDaysInMonth(DateTime date) {
// 获取当前月份的第一天
DateTime firstDayOfMonth = DateTime(date.year, date.month, 1);
// 获取当前月份的最后一天
DateTime lastDayOfMonth = DateTime(date.year, date.month + 1, 0);
List<DateTime> days = [];
// 获取该月的所有日期
for (int i = 0; i < lastDayOfMonth.day; i++) {
days.add(firstDayOfMonth.add(Duration(days: i)));
}
return days;
}
List<List<DateTime>> getCalendarRows(List<DateTime> daysInMonth) {
// 获取该月所有日期后,处理为 7 列的格式
List<List<DateTime>> calendarRows = [];
int firstWeekday = daysInMonth.first.weekday; // 获取该月第一天是周几
int emptyDays = (firstWeekday == 7 ? 0 : firstWeekday) - 1; // 调整为空白天数
List<DateTime> row = [];
for (int i = 0; i < emptyDays; i++) {
row.add(DateTime(0)); // 填充空白日期
}
for (var day in daysInMonth) {
row.add(day);
if (row.length == 7) {
// 如果当前行满了 7 个日期,则添加到 calendarRows 中,并重置 row
calendarRows.add(List.from(row));
row.clear();
}
}
if (row.isNotEmpty) {
// 如果最后一行的日期不足 7 个,则补充空白日期
while (row.length < 7) {
row.add(DateTime(0)); // 填充空白日期
}
calendarRows.add(List.from(row)); // 添加最后一行
}
return calendarRows;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Map<String, dynamic>> showLabel = [ List<Map<String, dynamic>> showLabel = [
{ {"level": 1, "name": "优秀", "color": Color(0xFF4CAF50)},
"level": 1, {"level": 2, "name": "良好", "color": Color(0xFF8BC34A)},
"name": "优秀", {"level": 3, "name": "合格", "color": Color(0xFFFFC107)},
"color": Color(0xFF4CAF50), // 绿色 {"level": 4, "name": "注意", "color": Color(0xFFF44336)},
}, {"level": 5, "name": "无报告", "color": Color(0xFF9E9E9E)},
{
"level": 2,
"name": "良好",
"color": Color(0xFF8BC34A), // 浅绿
},
{
"level": 3,
"name": "合格",
"color": Color(0xFFFFC107), // 黄色
},
{
"level": 4,
"name": "注意",
"color": Color(0xFFF44336), // 红色
},
{
"level": 5,
"name": "无报告",
"color": Color(0xFF9E9E9E), // 灰色
},
]; ];
List sleepData = [];
// 获取当前月的所有日期
List<DateTime> daysInMonth = getDaysInMonth(_currentDate);
// 获取按行排列的日期
List<List<DateTime>> calendarRows = getCalendarRows(daysInMonth);
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(0),
bottomRight: Radius.circular(0),
topLeft: Radius.circular(20.rpx), topLeft: Radius.circular(20.rpx),
topRight: Radius.circular(20.rpx), topRight: Radius.circular(20.rpx),
), ),
@@ -117,46 +57,51 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
children: [ children: [
Container( Container(
width: double.infinity, width: double.infinity,
// height: MediaQuery.sizeOf(context).height * 0.055, constraints: BoxConstraints(minHeight: 90.rpx),
constraints: BoxConstraints(
minHeight: 90.rpx,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF313541), color: const Color(0xFF313541),
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(0),
bottomRight: Radius.circular(0),
topLeft: Radius.circular(20.rpx), topLeft: Radius.circular(20.rpx),
topRight: Radius.circular(20.rpx), topRight: Radius.circular(20.rpx),
), ),
), ),
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding:
65.rpx, EdgeInsetsDirectional.fromSTEB(65.rpx, 0.rpx, 65.rpx, 0.rpx),
0.rpx,
65.rpx,
0.rpx,
),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Icon( ClickableContainer(
Icons.arrow_back_ios_new, backgroundColor: Colors.transparent,
color: const Color(0xFF6D6F73), highlightColor: Colors.grey,
size: 24.rpx, padding: EdgeInsetsDirectional.fromSTEB(
), 8.rpx, 8.rpx, 8.rpx, 8.rpx),
Text( onTap: () => calendarController.previousMonth(),
'${_currentDate.year}${_currentDate.month}', child: Icon(
style: TextStyle( Icons.arrow_back_ios_new,
color: Colors.white, color: const Color(0xFF6D6F73),
fontSize: 30.rpx, size: 24.rpx,
letterSpacing: 0.0,
), ),
), ),
Icon( Obx(() => Text(
Icons.arrow_forward_ios, '${calendarController.displayedMonth.value.year}${calendarController.displayedMonth.value.month}',
color: const Color(0xFF6D6F73), style: TextStyle(
size: 24.rpx, color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0.0,
),
)),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey,
padding: EdgeInsetsDirectional.fromSTEB(
8.rpx, 8.rpx, 8.rpx, 8.rpx),
onTap: () => calendarController.nextMonth(),
child: Icon(
Icons.arrow_forward_ios,
color: const Color(0xFF6D6F73),
size: 24.rpx,
),
), ),
], ],
), ),
@@ -164,97 +109,112 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
), ),
Container( Container(
width: double.infinity, width: double.infinity,
constraints: BoxConstraints( constraints: BoxConstraints(minHeight: 720.rpx),
minHeight: 720.rpx, decoration: const BoxDecoration(color: Color(0xFF242835)),
),
decoration: const BoxDecoration(
color: Color(0xFF242835),
),
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
65.rpx, 65.rpx, 13.rpx, 65.rpx, 38.rpx),
13.rpx, child: Obx(() {
65.rpx, final daysInMonth = calendarController.getDaysInMonth();
38.rpx, final calendarRows =
), calendarController.getCalendarRows(daysInMonth);
child: Column( final selectedDate = calendarController.selectedDate.value;
mainAxisSize: MainAxisSize.max,
children: [ return Column(
// Weekdays Header mainAxisSize: MainAxisSize.max,
Container( children: [
constraints: BoxConstraints(minHeight: 90.rpx), // Weekdays Header
child: Row( Container(
children: [ constraints: BoxConstraints(minHeight: 90.rpx),
for (var day in ["", "", "", "", "", "", ""]) child: Row(
Expanded( children: [
child: Center( for (var day in ["", "", "", "", "", "", ""])
child: Text( Expanded(
day, child: Center(
style: TextStyle( child: Text(
color: stringToColor("#FFFFFF"), day,
fontSize: AppConstants().normal_text_fontSize, style: TextStyle(
color: stringToColor("#FFFFFF"),
fontSize:
AppConstants().normal_text_fontSize,
),
), ),
), ),
), ),
), ],
], ),
), ),
), // Calendar days
// 日历显示部分 Column(
Column( children: calendarRows.map((week) {
children: calendarRows.map((week) { return Row(
return Row( mainAxisAlignment: MainAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, // 保证每一行左对齐 children: week.map((date) {
children: week.map((date) { if (date.year == 0) {
return Expanded( return Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.all(4.rpx), padding: EdgeInsets.all(0.rpx),
child: date.year != 0 // 如果是空白日期就不显示 child: SizedBox.shrink(),
? SleepdateWidget(date: date) ),
: SizedBox.shrink(), );
), }
); final isSelected = selectedDate != null &&
}).toList(), date.year == selectedDate.year &&
); date.month == selectedDate.month &&
}).toList(), date.day == selectedDate.day;
), return Expanded(
SizedBox( child: SleepdateWidget(
height: 55.rpx, date: date,
), isSelected: isSelected,
Wrap( onTap: () {
direction: Axis.horizontal, // 默认是水平排列的,可以去掉这行 calendarController.selectDate(date);
spacing: 20.rpx, // 水平间距 if (widget.onDateSelected != null) {
runSpacing: 20.rpx, // 垂直间距 widget.onDateSelected!(date);
children: showLabel.map<Widget>((item) { }
return Container( print(date);
padding: EdgeInsets.all(5.rpx), // 可选,添加一点间距 Get.back();
child: Row( },
mainAxisSize: MainAxisSize.min, // 确保 Row 不会占满整个宽度
children: [
Container(
width: 20.rpx,
height: 20.rpx,
decoration: BoxDecoration(
color: item["color"],
borderRadius:
BorderRadius.circular(10.rpx), // 圆形效果
), ),
), );
SizedBox(width: 8.rpx), // 标签和文本之间的间距 }).toList(),
Text( );
item["name"], }).toList(),
style: TextStyle( ),
color: Colors.white, SizedBox(height: 55.rpx),
fontSize: 24.rpx, Wrap(
spacing: 20.rpx,
runSpacing: 20.rpx,
children: showLabel.map<Widget>((item) {
return Container(
padding: EdgeInsets.all(5.rpx),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 20.rpx,
height: 20.rpx,
decoration: BoxDecoration(
color: item["color"],
borderRadius: BorderRadius.circular(10.rpx),
),
), ),
), SizedBox(width: 8.rpx),
], Text(
), item["name"],
); style: TextStyle(
}).toList(), color: Colors.white,
), fontSize: 24.rpx,
], ),
), ),
],
),
);
}).toList(),
),
],
);
}),
), ),
), ),
], ],
@@ -262,3 +222,5 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
); );
} }
} }

View File

@@ -1,34 +1,49 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
class SleepdateWidget extends StatelessWidget { class SleepdateWidget extends StatelessWidget {
final DateTime date; final DateTime date;
final bool isSelected;
final VoidCallback onTap;
const SleepdateWidget({super.key, required this.date}); const SleepdateWidget({
super.key,
required this.date,
required this.isSelected,
required this.onTap,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return ClickableContainer(
width: 90.rpx, onTap: onTap,
height: 90.rpx, backgroundColor: Colors.transparent,
decoration: BoxDecoration( highlightColor: Colors.transparent,
borderRadius: BorderRadius.circular(30.rpx), padding: EdgeInsets.all(4.rpx),
), child: Container(
child: Padding( width: 90.rpx,
padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx), height: 90.rpx,
child: Container( decoration: BoxDecoration(
decoration: BoxDecoration( borderRadius: BorderRadius.circular(30.rpx),
color: Color(0xFFDC1C1C), // 默认红色 color: isSelected ? Colors.black : Colors.transparent,
shape: BoxShape.circle, ),
), child: Padding(
child: Align( padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx),
alignment: AlignmentDirectional(0, 0), child: Container(
child: Text( decoration: BoxDecoration(
'${date.day}', color: Color(0xFFDC1C1C),
style: TextStyle( shape: BoxShape.circle,
color: Colors.white, ),
fontSize: 26.rpx, child: Align(
letterSpacing: 0.0, alignment: AlignmentDirectional(0, 0),
child: Text(
'${date.day}',
style: TextStyle(
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
), ),
), ),
), ),

View File

@@ -30,7 +30,9 @@ class ClickableContainer extends StatelessWidget {
child: InkWell( child: InkWell(
borderRadius: BorderRadius.circular(borderRadius), borderRadius: BorderRadius.circular(borderRadius),
onTap: onTap, onTap: onTap,
splashColor: highlightColor.withOpacity(0.5), splashColor: highlightColor == Colors.transparent
? Colors.transparent
: highlightColor.withOpacity(0.5),
child: Padding( child: Padding(
padding: padding, padding: padding,
child: child, child: child,

View File

@@ -86,8 +86,8 @@ Future<bool> sendWifiSetting(wifiItem, String password, THapp tHapp) async {
final success = await tHapp.send(cmd, true, (log) { final success = await tHapp.send(cmd, true, (log) {
if (log.log.contains("update parm is successful")) { if (log.log.contains("update parm is successful")) {
print("[wifi456]:" + log.log); print("[wifi456]:" + log.log);
edm.EasyDartModule.logger.info("WiFi配置成功-》log:$log"); edm.EasyDartModule.logger.info("WiFi配置参数成功-》log:$log");
DailyLogUtils.writeLog("WiFi配置成功->log:$log"); DailyLogUtils.writeLog("WiFi配置参数成功->log:$log");
log.result = true; log.result = true;
log.over = true; log.over = true;
return true; return true;
@@ -107,24 +107,21 @@ Future<bool> sendWifiSetting(wifiItem, String password, THapp tHapp) async {
} }
} }
getDeviceWifiStatus(THapp tHapp) async { getDeviceWifiStatus(THapp tHapp, int times) async {
edm.EasyDartModule.logger.info("发送请求设备已配置网络状态指令"); edm.EasyDartModule.logger.info("发送请求设备已配置网络状态指令");
DailyLogUtils.writeLog("发送请求设备已配置网络状态指令"); DailyLogUtils.writeLog("发送请求设备已配置网络状态指令");
try {
var result = await tHapp.send( var result = await tHapp.send("at+system info", true, (ss) {
"at+system info",
true,
(ss) {
var log = ss.log; var log = ss.log;
// 匹配设备状态 // 匹配设备状态
final statusMatch = RegExp(r'status=([^\s]+)').firstMatch(log); final statusMatch = RegExp(r'Status=([^\s]+)').firstMatch(log);
final status = statusMatch?.group(1); final status = statusMatch?.group(1);
if (status != null) { if (status != null) {
print('提取到的 status: $status'); print('提取到的 status: $status');
// 如果设备连接状态是 "connect",继续检测 // 如果设备连接状态是 "connect",继续检测
if (status == 'connect') { if (status.contains('connect')) {
ss.result = true; ss.result = true;
ss.over = true; ss.over = true;
@@ -159,8 +156,10 @@ getDeviceWifiStatus(THapp tHapp) async {
// 未找到状态或Wi-Fi信息时返回 false // 未找到状态或Wi-Fi信息时返回 false
return false; return false;
}, }, times);
);
return result; return result;
} catch (e) {
print(e);
}
} }

View File

@@ -0,0 +1,59 @@
import 'package:ef/ef.dart';
class CalendarController extends GetControllerEx {
Rx<DateTime> displayedMonth = DateTime.now().obs;
Rx<DateTime?> selectedDate = Rx<DateTime?>(null);
List<DateTime> getDaysInMonth() {
DateTime firstDayOfMonth =
DateTime(displayedMonth.value.year, displayedMonth.value.month, 1);
DateTime lastDayOfMonth =
DateTime(displayedMonth.value.year, displayedMonth.value.month + 1, 0);
List<DateTime> days = [];
for (int i = 0; i < lastDayOfMonth.day; i++) {
days.add(firstDayOfMonth.add(Duration(days: i)));
}
return days;
}
List<List<DateTime>> getCalendarRows(List<DateTime> daysInMonth) {
List<List<DateTime>> calendarRows = [];
int firstWeekday = daysInMonth.first.weekday;
int emptyDays = (firstWeekday == 7 ? 6 : firstWeekday - 1);
List<DateTime> row = [];
for (int i = 0; i < emptyDays; i++) {
row.add(DateTime(0));
}
for (var day in daysInMonth) {
row.add(day);
if (row.length == 7) {
calendarRows.add(List.from(row));
row.clear();
}
}
if (row.isNotEmpty) {
while (row.length < 7) {
row.add(DateTime(0));
}
calendarRows.add(List.from(row));
}
return calendarRows;
}
void previousMonth() {
displayedMonth.value =
DateTime(displayedMonth.value.year, displayedMonth.value.month - 1, 1);
}
void nextMonth() {
displayedMonth.value =
DateTime(displayedMonth.value.year, displayedMonth.value.month + 1, 1);
}
void selectDate(DateTime date) {
selectedDate.value = date;
}
}

View File

@@ -22,9 +22,9 @@ class BlueteethBindModel {
double? singal = -70; double? singal = -70;
@JsonKey(ignore: true) @JsonKey(ignore: true)
List<BleDeviceData>? devicelist = [];//蓝牙扫描 List<BleDeviceData>? devicelist = []; //蓝牙扫描
@JsonKey(ignore: true) @JsonKey(ignore: true)
List<BleDeviceData>? betDevicelist = [];//网络状态 List<BleDeviceData>? betDevicelist = []; //网络状态
@JsonKey(ignore: true) @JsonKey(ignore: true)
List? blelist = []; List? blelist = [];
@@ -67,6 +67,7 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
RxString scanMac = "".obs; RxString scanMac = "".obs;
String? currentDeviceMac; String? currentDeviceMac;
RxString? cid = "".obs ;//校准id
// 安全展示 TopSlideNotification // 安全展示 TopSlideNotification
void safeShowNotification(String msg) { void safeShowNotification(String msg) {
@@ -162,7 +163,8 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
if (response.data['data'] != null && response.data['data'] is List) { if (response.data['data'] != null && response.data['data'] is List) {
List<dynamic> responseList = response.data['data']; List<dynamic> responseList = response.data['data'];
Map<String, BleDeviceData> deviceMap = { Map<String, BleDeviceData> deviceMap = {
for (var d in model.devicelist!) if (d.mac != null) d.mac!: d for (var d in model.devicelist!)
if (d.mac != null) d.mac!: d
}; };
List<String> slaveMacsToRemove = []; List<String> slaveMacsToRemove = [];
@@ -190,7 +192,6 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
model.betDevicelist = []; model.betDevicelist = [];
} }
updateAll(); updateAll();
return res; return res;
} }
@@ -212,16 +213,16 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
String serviceApi = ServiceConstant.device_bind; String serviceApi = ServiceConstant.device_bind;
String queryUrl = "$serviceAddress$serviceName$serviceApi"; String queryUrl = "$serviceAddress$serviceName$serviceApi";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var data = { var data = {
"deviceType": 1, "deviceType": 1,
"mac": d.mac, "mac": d.mac,
@@ -267,16 +268,16 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
String serviceApi = ServiceConstant.device_bind; String serviceApi = ServiceConstant.device_bind;
String queryUrl = "$serviceAddress$serviceName$serviceApi"; String queryUrl = "$serviceAddress$serviceName$serviceApi";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var data = { var data = {
"deviceType": 1, "deviceType": 1,
"mac": mac, "mac": mac,

View File

@@ -52,17 +52,17 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
String serviceApi = ServiceConstant.device_list; String serviceApi = ServiceConstant.device_list;
String queryUrl = String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?bindNum=1"; "${serviceAddress}${serviceName}${serviceApi}?bindNum=1";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var response = await EasyDartModule.dio.get(queryUrl); var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) { if (response != null) {
var responseData = var responseData =
@@ -94,17 +94,17 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
String serviceApi = ServiceConstant.device_list; String serviceApi = ServiceConstant.device_list;
String queryUrl = String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?bindType=${model.type}${key != null ? '&key=$key' : ''}"; "${serviceAddress}${serviceName}${serviceApi}?bindType=${model.type}${key != null ? '&key=$key' : ''}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var response = await EasyDartModule.dio.get(queryUrl); var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) { if (response != null) {
var responseData = var responseData =
@@ -137,16 +137,16 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
String serviceApi = ServiceConstant.device_bind; String serviceApi = ServiceConstant.device_bind;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
final data = { final data = {
"mac": device['mac'], "mac": device['mac'],
}; };
@@ -205,16 +205,16 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
try { try {
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var response = await EasyDartModule.dio.get(queryUrl); var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) { if (response != null) {
var responseData = response.data is String var responseData = response.data is String
@@ -273,16 +273,16 @@ class BodyDeviceController extends GetControllerEx<BodyDeviceModel> {
String serviceApi = ServiceConstant.device_show; String serviceApi = ServiceConstant.device_show;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var data = { var data = {
"id": device['_id'], "id": device['_id'],
"show": !device['show'], "show": !device['show'],

View File

@@ -29,4 +29,6 @@ class DeviceCalibrationController
RxInt bed_calibration = 0.obs; //0.未完成 1.完成 RxInt bed_calibration = 0.obs; //0.未完成 1.完成
RxInt position_calibration = 0.obs; //0.未完成 1.完成 RxInt position_calibration = 0.obs; //0.未完成 1.完成
RxInt bed_type = 0.obs; //0.单人 1.双人 RxInt bed_type = 0.obs; //0.单人 1.双人
RxString tips = "开始校准".tr.obs;
bool complete = false; //校准完成
} }

View File

@@ -85,6 +85,7 @@ class DeviceShareController extends GetControllerEx<DeviceShareModel> {
EasyDartModule.logger.info("分享设备"); EasyDartModule.logger.info("分享设备");
DailyLogUtils.writeLog("分享设备"); DailyLogUtils.writeLog("分享设备");
try { try {
account.value = account.value.trim();
if (account.value == null || account.value.isEmpty) { if (account.value == null || account.value.isEmpty) {
apiResponse.msg = "请输入手机号或者邮箱".tr; apiResponse.msg = "请输入手机号或者邮箱".tr;
return apiResponse; return apiResponse;

View File

@@ -11,6 +11,7 @@ import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/ServiceConstant.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/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/time/countdown_controller.dart'; import 'package:vbvs_app/controller/time/countdown_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
@@ -125,6 +126,7 @@ class LoginController extends GetControllerEx<LoginModel> {
apiResponse.msg = "其他手机登录页.请输入手机号".tr; apiResponse.msg = "其他手机登录页.请输入手机号".tr;
return apiResponse; return apiResponse;
} }
model.phone = model.phone!.trim();
if (!MyUtils.isValidPhoneNumber(model.phone!) && if (!MyUtils.isValidPhoneNumber(model.phone!) &&
!MyUtils.isValidEmail(model.phone!)) { !MyUtils.isValidEmail(model.phone!)) {
apiResponse.msg = '其他手机登录页.不正确手机号'.tr; apiResponse.msg = '其他手机登录页.不正确手机号'.tr;
@@ -135,16 +137,16 @@ class LoginController extends GetControllerEx<LoginModel> {
String serviceApi = ServiceConstant.send_code; String serviceApi = ServiceConstant.send_code;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var data = { var data = {
"userName": model.phone, "userName": model.phone,
}; };
@@ -201,7 +203,33 @@ class LoginController extends GetControllerEx<LoginModel> {
}); });
} }
loginByWechatCode(String code) {} Future<ApiResponse> loginByWechatCode(String code) async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.login;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = "";
var data = {
"type": 2,
"password": code,
};
ApiResponse apiResponse = await requestWithLog(
logTitle: "微信登录",
method: MyHttpMethod.post,
queryUrl: queryUrl,
data: data);
if (apiResponse.code == HttpStatusCodes.ok) {
UserInfoController userInfoController = Get.find();
userInfoController.model.login = 1;
userInfoController.model.user = UserModel.fromJson(apiResponse.data);
String token = apiResponse.rawResponse.headers['token']!.first;
EasyDartModule.dio.token = token;
final box = GetStorage();
box.write('token', token); // 存储 token
box.write('user', userInfoController.model.user!.toJson()); // 存储用户信息
}
return apiResponse;
}
//退出登录 //退出登录
// Future<void> logout() async { // Future<void> logout() async {

View File

@@ -56,19 +56,9 @@ class PersonController extends GetControllerEx<PersonModel> {
RxInt gender = 1.obs; RxInt gender = 1.obs;
RxString birthday = "".obs; RxString birthday = "".obs;
RxInt weight = 65.obs; RxInt weight = 65.obs;
DateTime? dateTime; //选择时间 DateTime? dateTime = DateTime.now(); //选择时间
RxList diseaseList = [].obs; RxList diseaseList = [].obs;
//保存人员资料
// void savePersonData() {
// print("id->" + currentPersonId.value);
// print("name->" + name.value);
// print("gender->${gender.value}");
// print("生日->${birthday.value}");
// print("体重->${weight.value}");
// print("慢病->${selectedDiseaseIds.value}");
// }
Future<ApiResponse> savePersonData() async { Future<ApiResponse> savePersonData() async {
try { try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "蓝牙绑定.绑定失败".tr); ApiResponse apiResponse = ApiResponse(code: -1, msg: "蓝牙绑定.绑定失败".tr);
@@ -77,24 +67,24 @@ class PersonController extends GetControllerEx<PersonModel> {
String serviceApi = ServiceConstant.person_info; String serviceApi = ServiceConstant.person_info;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
if (name.value.isEmpty) { if (name.value.isEmpty) {
apiResponse.msg = "请输入姓名".tr; apiResponse.msg = "请输入姓名".tr;
return apiResponse; return apiResponse;
} }
if (birthday.value.isEmpty) { // if (birthday.value.isEmpty) {
apiResponse.msg = "请选择生日".tr; // apiResponse.msg = "请选择生日".tr;
return apiResponse; // return apiResponse;
} // }
if (weight.value == 0) { if (weight.value == 0) {
apiResponse.msg = "请输入体重".tr; apiResponse.msg = "请输入体重".tr;
return apiResponse; return apiResponse;
@@ -104,7 +94,9 @@ class PersonController extends GetControllerEx<PersonModel> {
"id": currentPersonId.value, "id": currentPersonId.value,
"name": name.value, "name": name.value,
"gender": gender.value, "gender": gender.value,
"birthday": birthday.value, "birthday": (birthday.value == null || birthday.value!.isEmpty)
? MyUtils.formatBindTime(dateTime!)
: birthday.value,
"weight": weight.value, "weight": weight.value,
"disease": selectedDiseaseIds.value, "disease": selectedDiseaseIds.value,
}; };
@@ -137,7 +129,7 @@ class PersonController extends GetControllerEx<PersonModel> {
String serviceName = ServiceConstant.server_service; String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.person_info; String serviceApi = ServiceConstant.person_info;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;

View File

@@ -9,10 +9,14 @@ part of 'language_controller.dart';
LanguageModel _$LanguageModelFromJson(Map<String, dynamic> json) => LanguageModel _$LanguageModelFromJson(Map<String, dynamic> json) =>
LanguageModel() LanguageModel()
..filename = json['filename'] as String? ..filename = json['filename'] as String?
..language_name = json['language_name'] as String?; ..language_name = json['language_name'] as String?
..selected = json['selected'] as bool?
..language_code = json['language_code'] as String?;
Map<String, dynamic> _$LanguageModelToJson(LanguageModel instance) => Map<String, dynamic> _$LanguageModelToJson(LanguageModel instance) =>
<String, dynamic>{ <String, dynamic>{
'filename': instance.filename, 'filename': instance.filename,
'language_name': instance.language_name, 'language_name': instance.language_name,
'selected': instance.selected,
'language_code': instance.language_code,
}; };

View File

@@ -0,0 +1,33 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'sleep_report_controller.g.dart'; // 由json_serializable自动生成的部分
@JsonSerializable()
class SleepReportModel {
int? type = 1; //报告类型 1:日报 2.周报 3.月报
SleepReportModel();
// 从JSON反序列化时的异常处理
factory SleepReportModel.fromJson(Map<String, dynamic> json) {
try {
return _$SleepReportModelFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return SleepReportModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$SleepReportModelToJson(this);
}
class SleepReportController extends GetControllerEx<SleepReportModel> {
Rx<DateTime?> selectedDate = Rx<DateTime?>(null);
SleepReportController() {
attr = GetModel(SleepReportModel()).obs;
}
}

View File

@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sleep_report_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SleepReportModel _$SleepReportModelFromJson(Map<String, dynamic> json) =>
SleepReportModel()..type = (json['type'] as num?)?.toInt();
Map<String, dynamic> _$SleepReportModelToJson(SleepReportModel instance) =>
<String, dynamic>{
'type': instance.type,
};

View File

@@ -16,6 +16,7 @@ import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/util/CheckNetwork.dart'; import 'package:vbvs_app/common/util/CheckNetwork.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart'; import 'package:vbvs_app/common/util/CommonVariables.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/controller/date/CalendarController.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/device/device_calibration_controller.dart'; import 'package:vbvs_app/controller/device/device_calibration_controller.dart';
@@ -31,6 +32,7 @@ import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart'; import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart';
import 'package:vbvs_app/controller/setting/pdf/PdfController.dart'; import 'package:vbvs_app/controller/setting/pdf/PdfController.dart';
import 'package:vbvs_app/controller/sleep/sleep_report_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/time/countdown_controller.dart'; import 'package:vbvs_app/controller/time/countdown_controller.dart';
import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/language/AppLanguage.dart';
@@ -236,6 +238,8 @@ class MyApp extends StatelessWidget {
Get.lazyPut(() => DeviceCalibrationController()), Get.lazyPut(() => DeviceCalibrationController()),
Get.lazyPut(() => RepairController()), Get.lazyPut(() => RepairController()),
Get.lazyPut(() => PdfController()), Get.lazyPut(() => PdfController()),
Get.lazyPut(() => CalendarController()),
Get.lazyPut(() => SleepReportController()),
])); ]));
}); });
} }

View File

@@ -3,15 +3,27 @@ class ApiResponse<T> {
T? data; T? data;
String? msg; String? msg;
int? total; int? total;
dynamic rawResponse; // 原始 Dio 响应对象
ApiResponse({
required this.code,
this.data,
this.msg,
this.total,
this.rawResponse,
});
ApiResponse({required this.code, this.data, this.msg, this.total});
factory ApiResponse.fromJson( factory ApiResponse.fromJson(
Map<String, dynamic> json, T Function(Object?) fromJsonT) { Map<String, dynamic> json,
T Function(Object?) fromJsonT, {
dynamic rawResponse,
}) {
return ApiResponse<T>( return ApiResponse<T>(
code: json['code'] as int, code: json['code'] as int?,
data: json['data'] != null ? fromJsonT(json['data']) : null, data: json['data'] != null ? fromJsonT(json['data']) : null,
msg: json['msg'] as String?, msg: json['msg'] as String?,
total: json['total'] as int?, total: json['total'] as int?,
rawResponse: rawResponse, // 保留 Dio 原始响应对象
); );
} }
} }

View File

@@ -4,7 +4,9 @@ import 'package:flutter/material.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.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/component/base/SleepCalendarWidget.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/device_calibration_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
getOnePicker(context, List arr, int checkIndex, Function onSelectedItemChanged, getOnePicker(context, List arr, int checkIndex, Function onSelectedItemChanged,
@@ -789,7 +791,7 @@ void showProgressDialog(
ValueNotifier<bool> failureNotifier, ValueNotifier<bool> failureNotifier,
) { ) {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
DeviceCalibrationController deviceCalibrationController = Get.find();
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, // 点击对话框外部不可关闭 barrierDismissible: false, // 点击对话框外部不可关闭
@@ -826,23 +828,28 @@ void showProgressDialog(
if (Navigator.canPop(dialogContext)) { if (Navigator.canPop(dialogContext)) {
Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop();
} }
TopSlideNotification.show( // TopSlideNotification.show(
context, // context,
text: "设备校准失败".tr, // text: "设备校准失败".tr,
textColor: Colors.red, // textColor: Colors.red,
); // );
}); });
} else if (progress >= 1.0) { } else if (progress >= 100) {
// 延迟关闭弹窗和提示成功(可选) // 延迟关闭弹窗和提示成功(可选)
Future.delayed(Duration(milliseconds: 300), () { Future.delayed(Duration(milliseconds: 300), () {
if (Navigator.canPop(dialogContext)) { if (Navigator.canPop(dialogContext)) {
Navigator.of(dialogContext).pop(); Navigator.of(dialogContext).pop();
} }
TopSlideNotification.show( // TopSlideNotification.show(
context, // context,
text: "设备校准完成".tr, // text: "设备校准完成".tr,
textColor: themeController.currentColor.sc3, // );
); // Obx(() {
// TopSlideNotification.show(context,
// text:
// deviceCalibrationController.tips.value);
// return Container();
// });
}); });
} }
@@ -852,7 +859,7 @@ void showProgressDialog(
Text( Text(
isFailure isFailure
? '失败'.tr ? '失败'.tr
: '${(progress * 100).toStringAsFixed(0)}%', : '${(progress).toStringAsFixed(0)}%',
style: TextStyle( style: TextStyle(
fontSize: 26.rpx, fontSize: 26.rpx,
color: isFailure color: isFailure
@@ -877,22 +884,23 @@ void showProgressDialog(
width: progress * width: progress *
MediaQuery.of(context).size.width * MediaQuery.of(context).size.width *
0.8, 0.8,
height: 10.rpx, height: 21.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: isFailure colors: isFailure
? [themeController.currentColor.sc9] ? [themeController.currentColor.sc9]
: [ : [
themeController themeController
.currentColor.sc1, .currentColor.sc2,
themeController themeController
.currentColor.sc2, .currentColor.sc2,
], ],
begin: Alignment.centerLeft, begin: Alignment.centerLeft,
end: Alignment.centerRight, end: Alignment.centerRight,
), ),
borderRadius: borderRadius: BorderRadius.circular(
BorderRadius.circular(5.rpx), AppConstants().button_container_radius,
),
), ),
), ),
], ],
@@ -912,3 +920,30 @@ void showProgressDialog(
}, },
); );
} }
void showSleepCalendarBottomSheet({
required BuildContext context,
int? timestamp,
required void Function(DateTime selectedDate) onDateSelected,
}) {
showModalBottomSheet(
context: context,
isScrollControlled: false,
backgroundColor: Colors.transparent,
builder: (context) {
return Container(
decoration: BoxDecoration(
color: const Color(0xFF242835),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.rpx),
topRight: Radius.circular(20.rpx),
),
),
child: SleepCalendarWidget(
timestamp: timestamp,
onDateSelected: onDateSelected, // 传递回调下去
),
);
},
);
}

View File

@@ -536,9 +536,8 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
color: themeController color: themeController
.currentColor.sc3, .currentColor.sc3,
), ),
cursorColor: cursorColor: themeController
FlutterFlowTheme.of(context) .currentColor.sc3,
.primaryText,
), ),
), ),
), ),
@@ -602,6 +601,7 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
), ),
), ),
), ),
Obx(() { Obx(() {
final isEmpty = final isEmpty =
bodyDeviceController.deviceList.value.isEmpty; bodyDeviceController.deviceList.value.isEmpty;

View File

@@ -73,6 +73,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
final allTexts = [ final allTexts = [
"体征检测设备.首页展示".tr, "体征检测设备.首页展示".tr,
"体征检测设备.设备详情".tr, "体征检测设备.设备详情".tr,
"WIFI配置".tr,
"设备校准".tr, "设备校准".tr,
"分享设备".tr, "分享设备".tr,
"消息设置".tr, "消息设置".tr,
@@ -86,7 +87,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
final estimatedItemHeight = 60.rpx; // 每个菜单项的估算高度 final estimatedItemHeight = 60.rpx; // 每个菜单项的估算高度
//todo 更新菜单项,需要在此添加数量 //todo 更新菜单项,需要在此添加数量
final itemCount = final itemCount =
widget.device['bind_type'] == BindType.active.code ? 8 : 5; widget.device['bind_type'] == BindType.active.code ? 9 : 5;
final estimatedPopupHeight = final estimatedPopupHeight =
(itemCount * estimatedItemHeight) + 40.rpx; // 加上padding (itemCount * estimatedItemHeight) + 40.rpx; // 加上padding
@@ -140,12 +141,24 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
left: popupLeft, left: popupLeft,
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: ConstrainedBox( child: Container(
constraints: BoxConstraints( constraints: BoxConstraints(
// maxWidth: popupWidth, // maxWidth: popupWidth,
maxWidth: screenWidth, maxWidth: screenWidth,
maxHeight: actualPopupHeight, maxHeight: actualPopupHeight,
), ),
decoration: BoxDecoration(
color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(12.rpx),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 12.rpx,
spreadRadius: 1.rpx,
offset: Offset(0, 6.rpx),
),
],
),
child: SingleChildScrollView( child: SingleChildScrollView(
child: popupContent, child: popupContent,
), ),
@@ -164,18 +177,18 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
Widget _buildPopupContent() { Widget _buildPopupContent() {
final content = Container( final content = Container(
padding: EdgeInsets.all(20.rpx), padding: EdgeInsets.all(20.rpx),
decoration: BoxDecoration( // decoration: BoxDecoration(
color: themeController.currentColor.sc17, // color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(12.rpx), // borderRadius: BorderRadius.circular(12.rpx),
boxShadow: [ // boxShadow: [
BoxShadow( // BoxShadow(
color: Colors.black.withOpacity(0.2), // color: Colors.black.withOpacity(0.2),
blurRadius: 12.rpx, // blurRadius: 12.rpx,
spreadRadius: 1.rpx, // spreadRadius: 1.rpx,
offset: Offset(0, 6.rpx), // offset: Offset(0, 6.rpx),
), // ),
], // ],
), // ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: _buildMenuItems(), children: _buildMenuItems(),
@@ -250,6 +263,14 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
// dealWifi(widget.device['mac']); // dealWifi(widget.device['mac']);
// }, // },
// ), // ),
_buildMenuItem(
text: "WIFI配置".tr,
onTap: () {
_popupEntry?.remove();
_popupEntry = null;
dealWifi(widget.device['mac']);
},
),
_buildMenuItem( _buildMenuItem(
text: "设备校准".tr, text: "设备校准".tr,
onTap: () { onTap: () {
@@ -962,7 +983,6 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
personController.currentPersonId.value = personController.currentPersonId.value =
widget.device['_id']; widget.device['_id'];
} }
// Get.toNamed("/personPage");
await Get.toNamed("/updatePersonPage", await Get.toNamed("/updatePersonPage",
arguments: widget.device['bind_type']); arguments: widget.device['bind_type']);
bodyDeviceController.getDeviceList(); bodyDeviceController.getDeviceList();
@@ -1151,7 +1171,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
final themeController = Get.find<ThemeController>(); final themeController = Get.find<ThemeController>();
// 显示加载对话框 // 显示加载对话框
showLoadingDialog(Get.context!, title: "正在匹配设备...".tr); showLoadingDialog(Get.context!, title: "连接中...".tr);
// 设置超时定时器 // 设置超时定时器
Timer? timeoutTimer; Timer? timeoutTimer;
@@ -1204,26 +1224,27 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
try { try {
// 连接设备 // 连接设备
await targetDevice.device.connect(autoConnect: false); // await targetDevice.device.connect();
THapp bledevice = THapp(device: targetDevice.device);
// 检查连接状态 await bledevice.device.connect();
if (targetDevice.device.isConnected) { var res2 = bledevice.isConnected;
Navigator.of(Get.context!).pop(); // 关闭加载对话框 if (res2) {
Navigator.pop(context);
// 存储当前设备
blueteethBindController.currentDevice =
THapp(device: targetDevice.device);
// 跳转到WiFi配置页
Get.toNamed("/wifiPage");
TopSlideNotification.show( TopSlideNotification.show(
Get.context!, context,
text: "设备连接成功".tr, text: "蓝牙绑定.连接成功".tr,
textColor: themeController.currentColor.sc2, textColor: themeController.currentColor.sc2,
); );
blueteethBindController.currentDevice = bledevice;
// Get.toNamed("/wifiPage", arguments: {bledevice});
Get.toNamed("/wifiPage", arguments: 1);
} else { } else {
throw Exception("连接失败"); Navigator.pop(context);
TopSlideNotification.show(
context,
text: "蓝牙绑定.连接失败".tr,
textColor: themeController.currentColor.sc9,
);
} }
} catch (e) { } catch (e) {
Navigator.of(Get.context!).pop(); // 关闭加载对话框 Navigator.of(Get.context!).pop(); // 关闭加载对话框
@@ -1235,7 +1256,6 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
} }
} }
}); });
// 等待扫描完成 // 等待扫描完成
await Future.delayed(Duration(seconds: 20)); await Future.delayed(Duration(seconds: 20));
} catch (e) { } catch (e) {
@@ -1264,8 +1284,6 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
maxTextWidth = painter.width; maxTextWidth = painter.width;
} }
} }
// 加上 icon 宽度24.rpx间距10.rpxpadding左右 20.rpx
final iconWidth = 24.rpx; final iconWidth = 24.rpx;
final spacing = 10.rpx; final spacing = 10.rpx;
final horizontalPadding = 40.rpx; final horizontalPadding = 40.rpx;

View File

@@ -278,14 +278,21 @@ class _DeviceDetailPageState extends State<DeviceDetailPage> {
minHeight: 200.rpx, minHeight: 200.rpx,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: FlutterFlowTheme.of(context) color: Colors.transparent,
.secondaryBackground,
),
child: QrImageView(
data: '1234567890',
version: QrVersions.auto,
size: 200.0.rpx,
), ),
child: (widget.device['code']
?.toString()
.isNotEmpty ??
false)
? QrImageView(
data: widget.device['code'].toString(),
version: QrVersions.auto,
size: 200.0.rpx,
)
: Image.asset(
"assets/img/errorImg.jpeg",
fit: BoxFit.cover,
),
), ),
Container( Container(
height: 50.rpx, height: 50.rpx,
@@ -293,7 +300,11 @@ class _DeviceDetailPageState extends State<DeviceDetailPage> {
child: Align( child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx), alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text( child: Text(
'A35968956', (widget.device['code'] ?? '')
.toString()
.isNotEmpty
? widget.device['code'].toString()
: '未知数据'.tr,
style: FlutterFlowTheme.of(context) style: FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(

View File

@@ -34,14 +34,22 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
DeviceTypeController deviceTypeController = Get.find(); DeviceTypeController deviceTypeController = Get.find();
int maxBodyMotion = 1; int maxBodyMotion = 1;
String breathState = ""; // String breathState = "否";
String inBed = "离床".tr; // String inBed = "离床".tr;
// String onlineState = "离线".tr;
// Timer? _onlineTimer; // 添加 Timer 引用
// int bodyMotion = 0;
// int breathrate = 0;
// String snores = "否".tr;
// int heartrate = 0;
String breathState = "未知数据".tr;
String inBed = "未知数据".tr;
String onlineState = "离线".tr; String onlineState = "离线".tr;
Timer? _onlineTimer; // 添加 Timer 引用 Timer? _onlineTimer; // 添加 Timer 引用
int bodyMotion = 0; int bodyMotion = -1;
int breathrate = 0; int breathrate = -1;
String snores = "".tr; String snores = "未知数据".tr;
int heartrate = 0; int heartrate = -1;
@override @override
void initState() { void initState() {
@@ -67,6 +75,12 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
if (mounted) { if (mounted) {
setState(() { setState(() {
onlineState = "离线".tr; // 30 秒内没有接收到数据,设置为离线 onlineState = "离线".tr; // 30 秒内没有接收到数据,设置为离线
inBed = "未知数据".tr;
bodyMotion = -1;
heartrate = -1;
snores = "未知数据".tr;
breathrate = -1;
breathState = "未知数据".tr;
}); });
} }
}); });
@@ -162,338 +176,357 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
child: Padding( child: Padding(
padding: padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 29.rpx, 0.rpx, 0.rpx), EdgeInsetsDirectional.fromSTEB(0.rpx, 29.rpx, 0.rpx, 0.rpx),
child: SingleChildScrollView( child: Column(
child: Column( mainAxisSize: MainAxisSize.max,
mainAxisSize: MainAxisSize.max, children: [
children: [ Padding(
Padding( padding: EdgeInsetsDirectional.fromSTEB(
padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0.rpx, 30.rpx, 120.rpx),
30.rpx, 0.rpx, 30.rpx, 120.rpx), child: ClickableContainer(
child: ClickableContainer( backgroundColor: themeController.currentColor.sc5,
backgroundColor: themeController.currentColor.sc5, highlightColor:
highlightColor: themeController.currentColor.sc5, // 或你希望的点击水波纹颜色
themeController.currentColor.sc5, // 或你希望的点击水波纹颜色 borderRadius: AppConstants()
borderRadius: AppConstants() .normal_container_radius, // 如果你想加圆角可以设置 eg. 12.rpx
.normal_container_radius, // 如果你想加圆角可以设置 eg. 12.rpx padding: EdgeInsets.zero,
padding: EdgeInsets.zero, onTap: () {
onTap: () { print('点击了体征卡片');
print('点击了体征卡片'); },
}, child: Row(
child: Row( mainAxisSize: MainAxisSize.max,
mainAxisSize: MainAxisSize.max, children: [
children: [ Expanded(
Expanded( flex: 1,
flex: 1, child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.姓名'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.年龄'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${device['person']?['name'] ?? '未命名'.tr}',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(device['person']?['birthday'])) ?? '未知数据'.tr}',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
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)),
),
),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.体重'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${device['code'] ?? '未知数据'.tr}',
// "D11250300003",
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${device['person']?['weight'] ?? '未知数据'.tr}kg',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
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)),
),
),
],
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
66.rpx, 0, 66.rpx, 0),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/img/body_black.gif'), // 本地图片
fit: BoxFit.cover,
),
),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [ children: [
DeviceStatusInfoWidget( Row(
title: "在离床".tr, children: [
iconAsset: "assets/img/icon/bed_status.svg", Column(
value: inBed, crossAxisAlignment:
), CrossAxisAlignment.end,
DeviceStatusInfoWidget( children: [
title: "体动".tr, Text(
iconAsset: "assets/img/icon/bodymotion.svg", '实时体征.姓名'.tr,
value: "${bodyMotion}" ?? "未知数据".tr, style: FlutterFlowTheme.of(context)
), .bodyMedium
], .override(
), fontFamily: 'Inter',
Row( fontSize: 26.rpx,
mainAxisAlignment: letterSpacing: 0.0,
MainAxisAlignment.spaceBetween, color: themeController
children: [ .currentColor.sc4,
DeviceStatusInfoWidget( ),
title: "心率".tr, ),
iconAsset: "assets/img/icon/heart.svg", Text(
value: "${heartrate}", '实时体征.年龄'.tr,
), style: FlutterFlowTheme.of(context)
DeviceStatusInfoWidget( .bodyMedium
title: "打鼾".tr, .override(
iconAsset: "assets/img/icon/snore.svg", fontFamily: 'Inter',
value: '${snores}'.tr, fontSize: 26.rpx,
), letterSpacing: 0.0,
], color: themeController
), .currentColor.sc4,
Row( ),
mainAxisAlignment: ),
MainAxisAlignment.spaceBetween, ].divide(SizedBox(height: 34.rpx)),
children: [
DeviceStatusInfoWidget(
title: "呼吸".tr,
iconAsset: "assets/img/icon/breathe.svg",
value: '${breathrate}',
),
DeviceStatusInfoWidget(
title: "呼吸暂停".tr,
iconAsset:
"assets/img/icon/breathe_pause.svg",
value: '${breathState}',
),
],
),
].divide(SizedBox(height: 49.rpx)),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 67.rpx, 0.rpx, 0.rpx),
child: Container(
height: 40.rpx,
child: Text(
bodyMotion >= maxBodyMotion ? '请保持静止'.tr : "",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc9,
),
),
),
),
SizedBox(
height: 207.rpx,
),
ClickableContainer(
backgroundColor: Colors.transparent, // 可自定义背景色
highlightColor: Colors.white, // 点击涟漪颜色
borderRadius: 16.rpx, // 圆角大小,可按需调整
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 0.rpx),
onTap: () {},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
26.rpx, 26.rpx, 26.rpx, 26.rpx),
decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .primaryBackground
// .withOpacity(0.6), // 半透明背景
borderRadius: BorderRadius.circular(16.rpx),
border: Border.all(
// 设置边框颜色和宽度
color: themeController.currentColor.sc4, // 边框颜色
width: 2.rpx, // 边框宽度
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 8.rpx, 0, 0),
child: Container(
width: 23.rpx,
height: 23.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tips.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc3,
),
),
),
Expanded(
child: Text(
'实时体征.提示'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
), ),
), Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${device['person']?['name'] ?? '未命名'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(device['person']?['birthday'])) ?? '未知数据'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
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(width: 23.rpx)), ),
), Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.体重'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${device['code'] ?? '未知数据'.tr}',
// "D11250300003",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${device['person']?['weight'] ?? '未知数据'.tr}kg',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
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)),
),
),
],
), ),
), ),
SizedBox( ),
height: 26.rpx, Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
66.rpx, 0, 66.rpx, 0),
child: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage(
// 'assets/img/body_black.gif'), // 本地图片
// fit: BoxFit.cover,
// ),
// ),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
onlineState == "离线".tr
? 'assets/img/black_body_still.jpg' // 静态图
: 'assets/img/body_black.gif', // 动图
),
fit: BoxFit.cover,
),
),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "在离床".tr,
iconAsset:
"assets/img/icon/bed_status.svg",
value: inBed,
),
DeviceStatusInfoWidget(
title: "体动".tr,
iconAsset:
"assets/img/icon/bodymotion.svg",
value: (bodyMotion == null ||
bodyMotion == -1)
? "未知数据".tr
: "$bodyMotion",
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "心率".tr,
iconAsset: "assets/img/icon/heart.svg",
value: (heartrate == null ||
heartrate == -1)
? "未知数据".tr
: "$heartrate",
),
DeviceStatusInfoWidget(
title: "打鼾".tr,
iconAsset: "assets/img/icon/snore.svg",
value: '${snores}'.tr,
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "呼吸".tr,
iconAsset:
"assets/img/icon/breathe.svg",
value: (breathrate == null ||
breathrate == -1)
? "未知数据".tr
: "$breathrate",
),
DeviceStatusInfoWidget(
title: "呼吸暂停".tr,
iconAsset:
"assets/img/icon/breathe_pause.svg",
value: '${breathState}',
),
],
),
].divide(SizedBox(height: 49.rpx)),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 67.rpx, 0.rpx, 0.rpx),
child: Container(
height: 40.rpx,
child: Text(
bodyMotion >= maxBodyMotion ? '请保持静止'.tr : "",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc9,
),
),
),
),
// SizedBox(
// height: 207.rpx,
// ),
],
), ),
], )),
), ClickableContainer(
backgroundColor: Colors.transparent, // 可自定义背景色
highlightColor: Colors.white, // 点击涟漪颜色
borderRadius: 16.rpx, // 圆角大小,可按需调整
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 0.rpx),
onTap: () {},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
26.rpx, 26.rpx, 26.rpx, 26.rpx),
decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .primaryBackground
// .withOpacity(0.6), // 半透明背景
borderRadius: BorderRadius.circular(16.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: 0.5.rpx,
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 8.rpx, 0, 0),
child: Container(
width: 23.rpx,
height: 23.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tips.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc4,
),
),
),
Expanded(
child: Text(
'实时体征.提示'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
].divide(SizedBox(width: 23.rpx)),
),
),
),
SizedBox(
height: 26.rpx,
),
],
), ),
), ),
), ),

View File

@@ -7,7 +7,9 @@ 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/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.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/main_bottom/global_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/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';
@@ -176,9 +178,34 @@ class _EPageState extends State<BindDeviceSuccess> {
child: CustomCard( child: CustomCard(
borderRadius: borderRadius:
AppConstants().button_container_radius, // 圆角半径 AppConstants().button_container_radius, // 圆角半径
onTap: () { onTap: () async {
print('Button pressed ...'); PersonController personController = Get.find();
Get.toNamed("/deviceType"); String deviceID =
personController.currentPersonId.value;
BodyDeviceController bodyDeviceController =
Get.find();
await bodyDeviceController.getDeviceList();
List deviceList =
bodyDeviceController.deviceList.value;
if (deviceList != null && deviceList.isNotEmpty) {
// 查找第一个 _id 匹配的设备
final matchedDevice = deviceList.firstWhere(
(element) => element['_id'] == deviceID,
orElse: () => null,
);
if (matchedDevice != null) {
// 跳转并传入设备
Get.toNamed("/deviceSharePage",
arguments: matchedDevice);
} else {
print("未找到匹配的设备");
}
} else {
print("设备列表为空");
}
}, },
colors: [ colors: [
// 渐变色 // 渐变色

View File

@@ -494,9 +494,8 @@ class _BlueteethDevicePageState extends State<BlueteethDevicePage> {
fontSize: 26.rpx, fontSize: 26.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
cursorColor: cursorColor: themeController
FlutterFlowTheme.of(context) .currentColor.sc3,
.primaryText,
// validator: _model // validator: _model
// .textControllerValidator // .textControllerValidator
// .asValidator(context), // .asValidator(context),

View File

@@ -69,7 +69,7 @@ class _FancyCircleCheckboxState extends State<FancyCircleCheckbox>
color: widget.value color: widget.value
? widget.borderColor ? widget.borderColor
: widget.borderColor.withOpacity(0.5), : widget.borderColor.withOpacity(0.5),
width: 1, width: 1.rpx,
), ),
), ),
child: ScaleTransition( child: ScaleTransition(

View File

@@ -15,6 +15,7 @@ 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/device_calibration_controller.dart'; import 'package:vbvs_app/controller/device/device_calibration_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class CalibrationPage extends StatefulWidget { class CalibrationPage extends StatefulWidget {
int? type; //1.绑定时 2.绑定后 int? type; //1.绑定时 2.绑定后
@@ -26,16 +27,21 @@ class CalibrationPage extends StatefulWidget {
class _CalibrationPageState extends State<CalibrationPage> { class _CalibrationPageState extends State<CalibrationPage> {
DeviceCalibrationController deviceCalibrationController = Get.find(); DeviceCalibrationController deviceCalibrationController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
deviceCalibrationController.process.value = 0; deviceCalibrationController.process.value = 0;
deviceCalibrationController.bed_calibration.value = 0; deviceCalibrationController.bed_calibration.value = 0;
deviceCalibrationController.position_calibration.value = 0; deviceCalibrationController.position_calibration.value = 0;
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
} }
@override @override
void dispose() { void dispose() {
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
super.dispose(); super.dispose();
} }
@@ -144,8 +150,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
vertical: 10.rpx), // 可自定义内边距 vertical: 10.rpx), // 可自定义内边距
onTap: () { onTap: () {
deviceCalibrationController.process.value = 0; // deviceCalibrationController.process.value = 0;
deviceCalibrationController.updateAll(); // deviceCalibrationController.updateAll();
}, },
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
@@ -213,8 +219,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
vertical: 10.rpx), // 可根据需要调整上下内边距 vertical: 10.rpx), // 可根据需要调整上下内边距
onTap: () { onTap: () {
deviceCalibrationController.process.value = 1; // deviceCalibrationController.process.value = 1;
deviceCalibrationController.updateAll(); // deviceCalibrationController.updateAll();
}, },
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
@@ -483,56 +489,221 @@ class _CalibrationPageState extends State<CalibrationPage> {
child: CustomCard( child: CustomCard(
borderRadius: borderRadius:
AppConstants().button_container_radius, // 圆角半径 AppConstants().button_container_radius, // 圆角半径
// onTap: () async {
// BlueteethBindController blueteethBindController =
// Get.find();
// String serviceAddress = "http://192.168.1.80:8086";
// String serviceApi = ServiceConstant.start_calibration;
// String queryUrl = "${serviceAddress}${serviceApi}";
// requestWithLog(
// logTitle: "设备校准",
// method: MyHttpMethod.post,
// queryUrl: queryUrl,
// data: {
// "macA": blueteethBindController.currentDeviceMac,
// if (blueteethBindController.cid!.value.isNotEmpty)
// "id": blueteethBindController.cid!.value,
// },
// onSuccess: (res) {
// String cid = res.rawResponse.data['cid'];
// blueteethBindController.cid!.value = cid;
// final ValueNotifier<double> progressNotifier =
// ValueNotifier<double>(0.0);
// final ValueNotifier<bool> failureNotifier =
// ValueNotifier<bool>(false);
// Timer? pollingTimer;
// // 定义请求函数
// void requestCalibrationProgress() {
// String serviceAddress =
// "http://192.168.1.80:8086";
// String serviceApi =
// ServiceConstant.calibration_process;
// String queryUrl =
// "${serviceAddress}${serviceApi}?id=$cid";
// requestWithLog(
// logTitle: "设备校准进度",
// method: MyHttpMethod.get,
// queryUrl: queryUrl,
// onSuccess: (res) {
// print(res);
// deviceCalibrationController.tips.value =
// res.data['statusText'];
// if (res.data['per'] == 100) {
// TopSlideNotification.show(context,
// text: deviceCalibrationController
// .tips.value);
// }
// double process =
// (res.data['per'] ?? 0).toDouble();
// progressNotifier.value = process;
// if (process >= 100) {
// if (deviceCalibrationController
// .process.value ==
// 0) {
// deviceCalibrationController
// .bed_calibration.value = 1;
// deviceCalibrationController.updateAll();
// }
// if (deviceCalibrationController
// .process.value ==
// 1) {
// deviceCalibrationController
// .position_calibration.value = 1;
// deviceCalibrationController.updateAll();
// }
// deviceCalibrationController
// .process.value = 1;
// deviceCalibrationController.updateAll();
// pollingTimer?.cancel();
// }
// },
// onFailure: (res) {
// pollingTimer?.cancel();
// failureNotifier.value = true;
// TopSlideNotification.show(
// context,
// text: res.msg ?? "服务器.失败".tr,
// textColor:
// themeController.currentColor.sc9,
// );
// },
// );
// }
// // 启动轮询
// pollingTimer =
// Timer.periodic(Duration(seconds: 2), (timer) {
// requestCalibrationProgress();
// });
// // 初始调用一次
// requestCalibrationProgress();
// // 显示进度弹窗
// showProgressDialog(
// context, progressNotifier, failureNotifier);
// },
// onFailure: (res) {
// TopSlideNotification.show(
// context,
// text: res.msg ?? "服务器.失败".tr,
// textColor: themeController.currentColor.sc9,
// );
// },
// );
// },
onTap: () async { onTap: () async {
if (deviceCalibrationController.complete) {
showConfirmDialog(
context, Container(), "校准已经完成,是否重新开始校准?",
onConfirm: () {
BlueteethBindController blueteethBindController =
Get.find();
deviceCalibrationController.process.value = 0;
deviceCalibrationController
.bed_calibration.value = 0;
deviceCalibrationController
.position_calibration.value = 0;
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
}, onCancel: () {});
}
BlueteethBindController blueteethBindController = BlueteethBindController blueteethBindController =
Get.find(); Get.find();
String serviceAddress = "https://caibration.he-info.cn/";
String calibrationApi =
ServiceConstant.start_calibration;
String progressApi =
ServiceConstant.calibration_process;
String queryUrl = "$serviceAddress$calibrationApi";
final ValueNotifier<double> progressNotifier =
ValueNotifier<double>(0.0);
final ValueNotifier<bool> failureNotifier =
ValueNotifier<bool>(false);
Timer? pollingTimer;
Map<String, dynamic> data = {
"macA": blueteethBindController.currentDeviceMac,
};
// 是否是二次点击有cid表示进行第二阶段
bool isSecondStep =
blueteethBindController.cid?.value.isNotEmpty ??
false;
if (isSecondStep) {
data["id"] = blueteethBindController.cid!.value;
}
// 发起校准请求
requestWithLog( requestWithLog(
logTitle: "设备校准", logTitle: "设备校准",
method: MyHttpMethod.post, method: MyHttpMethod.post,
queryUrl: ServiceConstant.start_calibration, queryUrl: queryUrl,
data: { data: data,
"deviceId":
blueteethBindController.currentDeviceMac
},
onSuccess: (res) { onSuccess: (res) {
final ValueNotifier<double> progressNotifier = if (!isSecondStep) {
ValueNotifier<double>(0.0); // 保存第一次获取的 cid
final ValueNotifier<bool> failureNotifier = String cid = res.rawResponse.data['cid'];
ValueNotifier<bool>(false); blueteethBindController.cid!.value = cid;
Timer? pollingTimer; }
// 定义请求函数
void requestCalibrationProgress() { void requestCalibrationProgress() {
String cid = blueteethBindController.cid!.value;
String progressUrl =
"$serviceAddress$progressApi?id=$cid";
requestWithLog( requestWithLog(
logTitle: "设备校准进度", logTitle: "设备校准进度",
method: MyHttpMethod.post, method: MyHttpMethod.get,
queryUrl: ServiceConstant.calibration_process, queryUrl: progressUrl,
data: {
"deviceId":
blueteethBindController.currentDeviceMac
},
onSuccess: (res) { onSuccess: (res) {
double process = final data = res.data;
(res.data['process'] ?? 0).toDouble(); double per = (data['per'] ?? 0).toDouble();
progressNotifier.value = process; int currStep = data['currStep'] ?? -1;
bool status = data['status'] ?? false;
String tips = data['statusText'] ?? '';
if (process >= 100) { deviceCalibrationController.tips.value =
if (deviceCalibrationController tips;
.process.value == // progressNotifier.value =
0) { // (res.data['per'] ?? 0) / 100.0;
deviceCalibrationController progressNotifier.value = per;
.bed_calibration.value = 1;
deviceCalibrationController.updateAll(); if (!isSecondStep && per >= 100) {
} // 第一步完成:仅 per >= 100
if (deviceCalibrationController
.process.value ==
1) {
deviceCalibrationController
.position_calibration.value = 1;
deviceCalibrationController.updateAll();
}
pollingTimer?.cancel(); pollingTimer?.cancel();
TopSlideNotification.show(context,
text: tips);
deviceCalibrationController
.process.value = 1;
deviceCalibrationController
.bed_calibration.value = 1;
deviceCalibrationController.updateAll();
}
if (isSecondStep &&
per >= 100 &&
currStep == 5 &&
status == true) {
// 第二步完成per >= 100 && currStep == 5 && status == true
pollingTimer?.cancel();
TopSlideNotification.show(context,
text: "设备校准完成".tr);
// 可在这里执行校准完成后的业务逻辑更新
deviceCalibrationController
.bed_calibration.value = 1;
deviceCalibrationController
.position_calibration.value = 1;
deviceCalibrationController
.process.value = 1;
deviceCalibrationController.complete =
true;
deviceCalibrationController.updateAll();
} }
}, },
onFailure: (res) { onFailure: (res) {
@@ -548,15 +719,15 @@ class _CalibrationPageState extends State<CalibrationPage> {
); );
} }
// 启动轮询
pollingTimer =
Timer.periodic(Duration(seconds: 2), (timer) {
requestCalibrationProgress();
});
// 初始调用一次 // 初始调用一次
requestCalibrationProgress(); requestCalibrationProgress();
// 开始轮询
pollingTimer =
Timer.periodic(Duration(seconds: 2), (_) {
requestCalibrationProgress();
});
// 显示进度弹窗 // 显示进度弹窗
showProgressDialog( showProgressDialog(
context, progressNotifier, failureNotifier); context, progressNotifier, failureNotifier);
@@ -570,6 +741,7 @@ class _CalibrationPageState extends State<CalibrationPage> {
}, },
); );
}, },
colors: [ colors: [
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2, themeController.currentColor.sc2,

View File

@@ -207,9 +207,8 @@ class _DeviceShareListPageState extends State<DeviceShareListPage> {
fontSize: 26.rpx, fontSize: 26.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
cursorColor: cursorColor: themeController
FlutterFlowTheme.of(context) .currentColor.sc3,
.primaryText,
), ),
), ),
), ),

View File

@@ -1,6 +1,8 @@
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:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:fluwx/fluwx.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/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
@@ -8,6 +10,7 @@ import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/device_share_controller.dart'; import 'package:vbvs_app/controller/device/device_share_controller.dart';
import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/FancyCircleCheckbox.dart'; import 'package:vbvs_app/pages/device_bind/componnet/FancyCircleCheckbox.dart';
@@ -180,7 +183,9 @@ class _DeviceSharePageState extends State<DeviceSharePage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFF3EDED), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Align( child: Align(
@@ -250,8 +255,7 @@ class _DeviceSharePageState extends State<DeviceSharePage> {
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController.currentColor.sc3,
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController1Validator // validator: _model.textController1Validator
// .asValidator(context), // .asValidator(context),
), ),
@@ -371,9 +375,15 @@ class _DeviceSharePageState extends State<DeviceSharePage> {
child: CustomCard( child: CustomCard(
borderRadius: borderRadius:
AppConstants().button_container_radius, // 圆角半径 AppConstants().button_container_radius, // 圆角半径
onTap: () { onTap: () async {
TopSlideNotification.show(context, // TopSlideNotification.show(context,
text: "待开发功能".tr); // text: "待开发功能".tr);
LoginController loginController = Get.find();
// loginController.fluwx.share(WeChatShareTextModel(
// "太和e护分享链接",
// scene: WeChatScene.session));
final Uint8List data = await rootBundle.load('assets/img/camera.png').then((bd) => bd.buffer.asUint8List());
loginController.fluwx.share(WeChatShareWebPageModel("https://www.baidu.com",title: "标题",description: "描述",thumbData: data));
}, },
colors: [ colors: [
// 渐变色 // 渐变色

View File

@@ -18,7 +18,8 @@ import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class WifiPage extends StatefulWidget { class WifiPage extends StatefulWidget {
WifiPage({super.key}); var type;
WifiPage({super.key, required this.type});
@override @override
State<WifiPage> createState() => _WifiPageState(); State<WifiPage> createState() => _WifiPageState();
@@ -36,6 +37,8 @@ class _WifiPageState extends State<WifiPage> {
void initState() { void initState() {
super.initState(); super.initState();
blueteethBindController.wifiList = [].obs; blueteethBindController.wifiList = [].obs;
blueteethBindController.wifiStatus = 0.obs;
blueteethBindController.connect_wifi.value = {};
initWifiStatusAndWifiList(); initWifiStatusAndWifiList();
} }
@@ -91,45 +94,45 @@ class _WifiPageState extends State<WifiPage> {
left: 0, left: 0,
child: returnIconButtom, child: returnIconButtom,
), ),
Positioned( if (widget.type == null)
right: 20.rpx, Positioned(
child: CustomCard( right: 20.rpx,
borderRadius: 20.rpx, child: CustomCard(
onTap: () async { borderRadius: 20.rpx,
if (blueteethBindController.wifiStatus.value != 1) { onTap: () async {
TopSlideNotification.show( if (blueteethBindController.wifiStatus.value != 1) {
context, TopSlideNotification.show(
text: "wifi页.需配网".tr, context,
textColor: themeController.currentColor.sc9, text: "wifi页.需配网".tr,
); textColor: themeController.currentColor.sc9,
} );
Get.toNamed("/calibrationPage",arguments: 1); } else {
// Get.toNamed("/personPage"); Get.toNamed("/calibrationPage", arguments: 1);
// Get.toNamed("/bindDeviceSuccess"); }
}, },
colors: [ colors: [
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2, themeController.currentColor.sc2,
], ],
child: Container( child: Container(
width: 100.rpx, width: 100.rpx,
height: 60.rpx, height: 60.rpx,
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 0, 16.rpx, 0), 16.rpx, 0, 16.rpx, 0),
child: Text( child: Text(
'wifi页.跳过'.tr, 'wifi页.跳过'.tr,
style: FlutterFlowTheme.of(context) style: FlutterFlowTheme.of(context)
.titleSmall .titleSmall
.override( .override(
fontFamily: 'Inter Tight', fontFamily: 'Inter Tight',
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
),
), ),
), ),
), ),
),
], ],
), ),
), ),
@@ -207,25 +210,29 @@ class _WifiPageState extends State<WifiPage> {
.connect_wifi.value.isEmpty) { .connect_wifi.value.isEmpty) {
return Container(); return Container();
} else { } else {
return Row( return Padding(
mainAxisAlignment: padding: EdgeInsetsDirectional.fromSTEB(
MainAxisAlignment.spaceBetween, 30.rpx, 0.rpx, 30.rpx, 30.rpx),
children: [ child: Row(
Text( mainAxisAlignment:
blueteethBindController MainAxisAlignment.spaceBetween,
.connect_wifi.value['ssid'] ?? children: [
'未命名'.tr, Text(
style: TextStyle( blueteethBindController.connect_wifi
color: themeController .value['ssid'] ??
.currentColor.sc3, '未命名'.tr,
fontSize: AppConstants() style: TextStyle(
.title_text_fontSize, color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
),
), ),
), getWifiIconByRsso(
getWifiIconByRsso( blueteethBindController
blueteethBindController .connect_wifi.value),
.connect_wifi.value), ],
], ),
); );
} }
}) })
@@ -267,136 +274,6 @@ class _WifiPageState extends State<WifiPage> {
), ),
], ],
), ),
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '6503',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc3,
// ),
// ),
// Icon(
// Icons.wifi_outlined,
// size: 30.rpx,
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '6503',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc3,
// ),
// ),
// Icon(
// Icons.wifi_outlined,
// size: 30.rpx,
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '6503',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc3,
// ),
// ),
// Icon(
// Icons.wifi_outlined,
// size: 30.rpx,
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '6503',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc3,
// ),
// ),
// Icon(
// Icons.wifi_outlined,
// size: 30.rpx,
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '6503',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc3,
// ),
// ),
// Icon(
// Icons.wifi_outlined,
// size: 30.rpx,
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// ].divide(SizedBox(height: 67.rpx)),
// ),
Obx(() { Obx(() {
final sortedList = [ final sortedList = [
...blueteethBindController.wifiList.value ...blueteethBindController.wifiList.value
@@ -413,7 +290,7 @@ class _WifiPageState extends State<WifiPage> {
.currentColor.sc3, .currentColor.sc3,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
vertical: 0.rpx, vertical: 0.rpx,
horizontal: 20.rpx), horizontal: 0.rpx),
borderRadius: 16.rpx, borderRadius: 16.rpx,
onTap: () { onTap: () {
showWifiDialog( showWifiDialog(
@@ -573,9 +450,9 @@ class _WifiPageState extends State<WifiPage> {
color: Colors color: Colors
.black), .black),
cursorColor: cursorColor:
FlutterFlowTheme.of( themeController
context) .currentColor
.primaryText, .sc3,
); );
})), })),
), ),
@@ -591,21 +468,75 @@ class _WifiPageState extends State<WifiPage> {
.model.wifiPass!, .model.wifiPass!,
blueteethBindController blueteethBindController
.currentDevice!); .currentDevice!);
Navigator.pop(context); // Navigator.pop(context);
if (flag) { if (flag) {
TopSlideNotification.show( // bool wifiStatus =
context, // await getWifiStatus(
text: "wifi页.配网成功".tr, // blueteethBindController
textColor: // .currentDevice!);
themeController bool wifiStatus = false;
.currentColor var aa = await getDeviceWifiStatus(
.sc2, blueteethBindController
); .currentDevice!,
20);
if (aa != null &&
aa is Map) {
wifiStatus = true;
blueteethBindController
.connect_wifi
.value = aa;
} else {
blueteethBindController
.connect_wifi
.value = {};
}
blueteethBindController blueteethBindController
.wifiStatus.value = 1; .wifiStatus
.value =
wifiStatus == true
? 1
: 0;
blueteethBindController blueteethBindController
.updateAll(); .wifiStatus
.value =
wifiStatus == true
? 1
: 0;
if (wifiStatus) {
Navigator.pop(context);
TopSlideNotification
.show(
context,
text: "wifi页.配网成功".tr,
textColor:
themeController
.currentColor
.sc2,
);
blueteethBindController
.wifiStatus
.value = 1;
blueteethBindController
.updateAll();
} else {
Navigator.pop(context);
TopSlideNotification
.show(
context,
text: "wifi页.配网失败".tr,
textColor:
themeController
.currentColor
.sc9,
);
blueteethBindController
.wifiStatus
.value = 0;
blueteethBindController
.updateAll();
}
} else { } else {
Navigator.pop(context);
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "wifi页.配网失败".tr, text: "wifi页.配网失败".tr,
@@ -651,7 +582,6 @@ class _WifiPageState extends State<WifiPage> {
.divide(SizedBox(height: 67.rpx)), .divide(SizedBox(height: 67.rpx)),
); );
}), }),
ClickableContainer( ClickableContainer(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
highlightColor: Colors.white, highlightColor: Colors.white,
@@ -774,16 +704,14 @@ class _WifiPageState extends State<WifiPage> {
} }
if (onData.status == BleEventType.ready) { if (onData.status == BleEventType.ready) {
showLoadingDialog(context, title: "获取wifi列表中...".tr); showLoadingDialog(context, title: "获取wifi列表中...".tr);
bool wifiStatus = bool wifiStatus = false;
await getWifiStatus(blueteethBindController.currentDevice!); var aa = await getDeviceWifiStatus(
blueteethBindController.currentDevice!, 10);
if (aa != null && aa is Map) {
wifiStatus = true;
blueteethBindController.connect_wifi.value = aa;
}
blueteethBindController.wifiStatus.value = wifiStatus == true ? 1 : 0; blueteethBindController.wifiStatus.value = wifiStatus == true ? 1 : 0;
// if (wifiStatus) {
// Map connect_wifiInfo =
// await getDeviceWifiStatus(blueteethBindController.currentDevice!);
// if (connect_wifiInfo != null) {
// blueteethBindController.connect_wifi.value = connect_wifiInfo;
// }
// }
List wifiList = List wifiList =
await getWifiList(blueteethBindController.currentDevice!); await getWifiList(blueteethBindController.currentDevice!);
if (wifiList.length > 0) { if (wifiList.length > 0) {
@@ -827,77 +755,50 @@ class _WifiPageState extends State<WifiPage> {
} }
getWifiIconByRsso(wifiItem) { getWifiIconByRsso(wifiItem) {
if (wifiItem['rssi'] >= -30) { int? rssi = int.tryParse(wifiItem['rssi'].toString());
// return SvgPicture.asset(
// 'assets/img/icon/wifi4.svg', if (rssi != null) {
// width: 25.rpx, if (rssi >= -30) {
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置 return Container(
// color: themeController.currentColor.sc3, width: 40.rpx,
// ); height: 40.rpx,
return Container( clipBehavior: Clip.antiAlias,
width: 40.rpx, decoration: BoxDecoration(shape: BoxShape.circle),
height: 40.rpx, child: Image.asset("assets/img/wifi4.png"),
clipBehavior: Clip.antiAlias, );
decoration: BoxDecoration( } else if (rssi >= -45) {
shape: BoxShape.circle, return Container(
), width: 40.rpx,
child: Image.asset( height: 40.rpx,
"assets/img/wifi4.png", clipBehavior: Clip.antiAlias,
), decoration: BoxDecoration(shape: BoxShape.circle),
); child: Image.asset("assets/img/wifi3.png"),
} else if (wifiItem['rssi'] >= -45) { );
// return SvgPicture.asset( } else if (rssi >= -60) {
// 'assets/img/icon/wifi3.svg', return Container(
// width: 25.rpx, width: 40.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置 height: 40.rpx,
// color: themeController.currentColor.sc3, clipBehavior: Clip.antiAlias,
// ); decoration: BoxDecoration(shape: BoxShape.circle),
return Container( child: Image.asset("assets/img/wifi3.png"),
width: 40.rpx, );
height: 40.rpx, } else {
clipBehavior: Clip.antiAlias, return Container(
decoration: BoxDecoration( width: 40.rpx,
shape: BoxShape.circle, height: 40.rpx,
), clipBehavior: Clip.antiAlias,
child: Image.asset( decoration: BoxDecoration(shape: BoxShape.circle),
"assets/img/wifi3.png", child: Image.asset("assets/img/wifi1.png"),
), );
); }
} else if (wifiItem['rssi'] >= -60) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi2.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wifi3.png",
),
);
} else { } else {
// return SvgPicture.asset( // RSSI 无法解析时的默认显示
// 'assets/img/icon/wifi1.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container( return Container(
width: 40.rpx, width: 40.rpx,
height: 40.rpx, height: 40.rpx,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: BoxDecoration( decoration: BoxDecoration(shape: BoxShape.circle),
shape: BoxShape.circle, child: Image.asset("assets/img/wifi1.png"),
),
child: Image.asset(
"assets/img/wifi1.png",
),
); );
} }
} }

View File

@@ -3,11 +3,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
import 'package:vbvs_app/common/color/ServiceConstant.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/util/CheckNetwork.dart'; import 'package:vbvs_app/common/util/CheckNetwork.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart'; import 'package:vbvs_app/common/util/CommonVariables.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/requestWithLog.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/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
@@ -15,6 +18,7 @@ import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_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';
import 'package:vbvs_app/model/api_response.dart';
class LoginPage extends StatefulWidget { class LoginPage extends StatefulWidget {
const LoginPage({super.key}); const LoginPage({super.key});
@@ -54,7 +58,7 @@ class _EPageState extends State<LoginPage> {
int errCode = response.errCode ?? -9999; int errCode = response.errCode ?? -9999;
if (errCode == 0) { if (errCode == 0) {
// TODO 微信登录成功 传递code给后台 再操作逻辑 // TODO 微信登录成功 传递code给后台 再操作逻辑
String code = response.code ?? ""; String code = response.code ?? "";
//把微信登录返回的code传给后台剩下的事就交给后台处理 //把微信登录返回的code传给后台剩下的事就交给后台处理
//首次未注册的用户引导去手机号填写页面 //首次未注册的用户引导去手机号填写页面
//已注册的用户直接跳转首页 //已注册的用户直接跳转首页
@@ -62,8 +66,8 @@ class _EPageState extends State<LoginPage> {
showToast("网络未连接,请开启设备网络后重试"); showToast("网络未连接,请开启设备网络后重试");
return; return;
} }
String msg = await loginController.loginByWechatCode(code); ApiResponse msg = await loginController.loginByWechatCode(code);
if (msg.isEmpty) { if (msg.code == HttpStatusCodes.ok) {
// TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听 // TODO 操作全部跳转页面前成功以后移除监听,防止重复监听,其他方式登录成功也需要移出监听
loginController.fluwxCancelable?.cancel(); loginController.fluwxCancelable?.cancel();
// 登录成功移出网络检查监听 // 登录成功移出网络检查监听

View File

@@ -153,8 +153,9 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
AppConstants() AppConstants()
.button_container_radius), .button_container_radius),
border: Border.all( border: Border.all(
color: themeController.currentColor.sc3, color: themeController.currentColor.sc4
width: 1.rpx, .withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
constraints: BoxConstraints( constraints: BoxConstraints(
@@ -264,10 +265,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
color: themeController color: themeController
.currentColor.sc3, .currentColor.sc3,
), ),
cursorColor: cursorColor: themeController
FlutterFlowTheme.of( .currentColor.sc3,
context)
.primaryText,
// validator: _model // validator: _model
// .textControllerValidator // .textControllerValidator
// .asValidator(context), // .asValidator(context),
@@ -295,8 +294,9 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
AppConstants() AppConstants()
.button_container_radius), .button_container_radius),
border: Border.all( border: Border.all(
color: themeController.currentColor.sc3, color: themeController.currentColor.sc4
width: 1.rpx, .withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
constraints: BoxConstraints( constraints: BoxConstraints(
@@ -406,10 +406,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
color: themeController color: themeController
.currentColor.sc3, .currentColor.sc3,
), ),
cursorColor: cursorColor: themeController
FlutterFlowTheme.of( .currentColor.sc3,
context)
.primaryText,
// validator: _model // validator: _model
// .textControllerValidator // .textControllerValidator
// .asValidator(context), // .asValidator(context),

View File

@@ -5,6 +5,7 @@ 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:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
@@ -122,7 +123,7 @@ class MainPageBottomChange extends GetView<MainPageController> {
top: BorderSide( top: BorderSide(
color: themeController.currentColor.sc4 color: themeController.currentColor.sc4
.withOpacity(0.5), .withOpacity(0.5),
width: 0.5, width: AppConstants().border_width,
), ),
), ),
), ),
@@ -203,7 +204,7 @@ class MainPageBottomChange extends GetView<MainPageController> {
currentTime.difference(_lastBackPressedTime!) > Duration(seconds: 2)) { currentTime.difference(_lastBackPressedTime!) > Duration(seconds: 2)) {
_lastBackPressedTime = currentTime; _lastBackPressedTime = currentTime;
// showToast("再按一次退出程序", color: color_warning, closeTime: 2); // showToast("再按一次退出程序", color: color_warning, closeTime: 2);
TopSlideNotification.show(context,text: "滑动退出提醒".tr); TopSlideNotification.show(context, text: "滑动退出提醒".tr);
return false; // 阻止退出程序 return false; // 阻止退出程序
} else { } else {
return true; // 允许退出程序 return true; // 允许退出程序

View File

@@ -6,10 +6,10 @@ 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/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/component/base/SleepCalendarWidget.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/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/date/CalendarController.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_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';
@@ -26,6 +26,7 @@ class _MinePageState extends State<MinePage> {
GlobalController globalController = Get.find(); GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find(); UserInfoController userInfoController = Get.find();
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
CalendarController calendarController = Get.find();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -216,16 +217,25 @@ class _MinePageState extends State<MinePage> {
), ),
Text( Text(
login == 1 login == 1
? (userInfoController.model ? (() {
.user!.email != final user =
null
? userInfoController
.model.user!.email!
: MyUtils.hidePhoneNumber(
userInfoController userInfoController
.model .model.user!;
.user! if (user.email != null &&
.phone!)) user.email!
.isNotEmpty) {
return user.email!;
} else if (user.phone !=
null &&
user.phone!
.isNotEmpty) {
return MyUtils
.hidePhoneNumber(
user.phone!);
} else {
return "微信用户".tr;
}
})()
: "我的.未登录".tr, : "我的.未登录".tr,
style: style:
FlutterFlowTheme.of(context) FlutterFlowTheme.of(context)
@@ -629,32 +639,13 @@ class _MinePageState extends State<MinePage> {
); );
Get.toNamed("/loginPage"); Get.toNamed("/loginPage");
} else { } else {
// TopSlideNotification.show( TopSlideNotification.show(
// context, context,
// text: "待开发.提示".tr, text: "待开发.提示".tr,
// textColor: textColor:
// themeController.currentColor.sc2, themeController.currentColor.sc2,
// );
showModalBottomSheet(
context: context,
isScrollControlled: false, // 不需要滚动全屏
backgroundColor:
Colors.transparent, // 为了圆角和美观
builder: (context) {
return Container(
decoration: BoxDecoration(
color: const Color(
0xFF242835), // 你组件的底色
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.rpx),
topRight: Radius.circular(20.rpx),
),
),
child:
SleepCalendarWidget(), // 显示日历组件
);
},
); );
// Get.toNamed("/newSleepReportPage",arguments: DateTime.now().millisecondsSinceEpoch);
} }
}, },
child: Container( child: Container(

View File

@@ -36,13 +36,13 @@ class _EPageState extends State<PersonPage> {
super.initState(); super.initState();
personController.getDiseaseData().then((apiResponse) { personController.getDiseaseData().then((apiResponse) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
TopSlideNotification.show( if (apiResponse.code != HttpStatusCodes.ok) {
context, TopSlideNotification.show(
text: apiResponse.msg!, context,
textColor: apiResponse.code != HttpStatusCodes.ok text: apiResponse.msg ?? '',
? themeController.currentColor.sc9 textColor: themeController.currentColor.sc9,
: themeController.currentColor.sc2, );
); }
}); });
}); });
personController.selectedDiseaseIds.value = []; personController.selectedDiseaseIds.value = [];
@@ -50,7 +50,7 @@ class _EPageState extends State<PersonPage> {
personController.gender.value = 1; personController.gender.value = 1;
personController.birthday.value = ""; personController.birthday.value = "";
personController.weight.value = 65; personController.weight.value = 65;
personController.dateTime = null; personController.dateTime = DateTime.now();
} }
@override @override
@@ -162,7 +162,9 @@ class _EPageState extends State<PersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFF3EDED), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Align( child: Align(
@@ -232,8 +234,7 @@ class _EPageState extends State<PersonPage> {
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController.currentColor.sc3,
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController1Validator // validator: _model.textController1Validator
// .asValidator(context), // .asValidator(context),
), ),
@@ -463,7 +464,11 @@ class _EPageState extends State<PersonPage> {
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(color: Color(0xFFF3EDED)), border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
), ),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
@@ -514,7 +519,9 @@ class _EPageState extends State<PersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFF3EDED), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Align( child: Align(
@@ -544,8 +551,7 @@ class _EPageState extends State<PersonPage> {
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController.currentColor.sc3,
FlutterFlowTheme.of(context).primaryText,
decoration: InputDecoration( decoration: InputDecoration(
fillColor: Colors.transparent, fillColor: Colors.transparent,
isDense: true, isDense: true,
@@ -682,7 +688,9 @@ class _EPageState extends State<PersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.rpx), borderRadius: BorderRadius.circular(20.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFE9E3E3), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Padding( child: Padding(
@@ -697,7 +705,7 @@ class _EPageState extends State<PersonPage> {
0, 8.rpx, 0, 0), 0, 8.rpx, 0, 0),
child: Icon( child: Icon(
Icons.arrow_back, Icons.arrow_back,
color: Color(0xFFE4EBF0), color: themeController.currentColor.sc4,
size: 24.rpx, size: 24.rpx,
), ),
), ),
@@ -708,7 +716,8 @@ class _EPageState extends State<PersonPage> {
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
color: Color(0xFFEEF3F8), color:
themeController.currentColor.sc4,
fontSize: 26.rpx, fontSize: 26.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),

View File

@@ -39,20 +39,18 @@ class _UpdatePageState extends State<UpdatePersonPage> {
void initState() { void initState() {
super.initState(); super.initState();
personController.getDiseaseData().then((apiResponse) { personController.getDiseaseData().then((apiResponse) {
TopSlideNotification.show( if (apiResponse.code != HttpStatusCodes.ok) {
context, TopSlideNotification.show(
text: apiResponse.msg!, context,
textColor: apiResponse.code != HttpStatusCodes.ok text: apiResponse.msg ?? '',
? themeController.currentColor.sc9 textColor: themeController.currentColor.sc9,
: themeController.currentColor.sc2, );
); }
}); });
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print(widget.status);
print(widget.status);
return LayoutBuilder( return LayoutBuilder(
builder: (context, bodySize) => GestureDetector( builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
@@ -89,6 +87,7 @@ class _UpdatePageState extends State<UpdatePersonPage> {
fontSize: 30.rpx, fontSize: 30.rpx,
), ),
), ),
/// 左边返回按钮 /// 左边返回按钮
Positioned( Positioned(
left: 0, left: 0,
@@ -164,7 +163,9 @@ class _UpdatePageState extends State<UpdatePersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFF3EDED), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Align( child: Align(
@@ -234,8 +235,7 @@ class _UpdatePageState extends State<UpdatePersonPage> {
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController.currentColor.sc3,
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController1Validator // validator: _model.textController1Validator
// .asValidator(context), // .asValidator(context),
), ),
@@ -465,7 +465,11 @@ class _UpdatePageState extends State<UpdatePersonPage> {
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(color: Color(0xFFF3EDED)), border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
), ),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
@@ -516,7 +520,9 @@ class _UpdatePageState extends State<UpdatePersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx), borderRadius: BorderRadius.circular(50.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFF3EDED), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Align( child: Align(
@@ -546,8 +552,7 @@ class _UpdatePageState extends State<UpdatePersonPage> {
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController.currentColor.sc3,
FlutterFlowTheme.of(context).primaryText,
decoration: InputDecoration( decoration: InputDecoration(
fillColor: Colors.transparent, fillColor: Colors.transparent,
isDense: true, isDense: true,
@@ -676,7 +681,6 @@ class _UpdatePageState extends State<UpdatePersonPage> {
), ),
); );
}), }),
Padding( Padding(
padding: padding:
EdgeInsetsDirectional.fromSTEB(0, 152.rpx, 0, 0), EdgeInsetsDirectional.fromSTEB(0, 152.rpx, 0, 0),
@@ -685,7 +689,9 @@ class _UpdatePageState extends State<UpdatePersonPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.rpx), borderRadius: BorderRadius.circular(20.rpx),
border: Border.all( border: Border.all(
color: Color(0xFFE9E3E3), color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
child: Padding( child: Padding(
@@ -711,7 +717,8 @@ class _UpdatePageState extends State<UpdatePersonPage> {
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
color: Color(0xFFEEF3F8), color:
themeController.currentColor.sc4,
fontSize: 26.rpx, fontSize: 26.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),

View File

@@ -304,7 +304,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize, fontSize: AppConstants().normal_text_fontSize,
), ),
cursorColor: FlutterFlowTheme.of(context).primaryText, cursorColor: themeController
.currentColor.sc3,
), ),
), ),
), ),

View File

@@ -0,0 +1,102 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class SegmentData {
final Color color;
final double value;
SegmentData({required this.color, required this.value});
}
class SegmentedCirclePainter extends CustomPainter {
final List<SegmentData> segments;
final double strokeWidth;
final double gapAngle; // 每段之间的间隔角度(单位:度)
SegmentedCirclePainter({
required this.segments,
this.strokeWidth = 6.0,
this.gapAngle = 4.0,
});
@override
void paint(Canvas canvas, Size size) {
final double radius = size.width / 2;
final Offset center = Offset(size.width / 2, size.height / 2);
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.square;
final double totalValue = segments.fold(0, (sum, item) => sum + item.value);
final double totalGap = gapAngle * segments.length;
final double totalDrawAngle = 360.0 - totalGap;
double startAngle = -90.0; // 从顶部开始
for (var segment in segments) {
final double sweepAngle = (segment.value / totalValue) * totalDrawAngle;
paint.color = segment.color;
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius - strokeWidth / 2),
radians(startAngle),
radians(sweepAngle),
false,
paint,
);
startAngle += sweepAngle + gapAngle;
}
}
double radians(double degrees) => degrees * 3.1415926 / 180;
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
class SegmentedCircleWithCenterWidget extends StatelessWidget {
final List<SegmentData> segments;
final double strokeWidth;
final double gapAngle;
final Widget centerWidget;
const SegmentedCircleWithCenterWidget({
Key? key,
required this.segments,
this.strokeWidth = 6.0,
this.gapAngle = 4.0,
required this.centerWidget,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.center,
children: [
CustomPaint(
size: Size(200, 200), // 设置圆的尺寸
painter: SegmentedCirclePainter(
segments: segments,
strokeWidth: strokeWidth,
gapAngle: gapAngle,
),
),
centerWidget, // 放置自定义的中心 Widget
Positioned(
right: 60.rpx, // 放置在右侧
child: SvgPicture.asset(
'assets/img/icon/add.svg',
width: 14.rpx,
height: 22.rpx,
color: themeController.currentColor.sc9,
),
),
],
);
}
}

View File

@@ -0,0 +1,178 @@
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/pages/sleep_report/component/SegmentedCirclePainter.dart';
class SleepScoreWidget extends StatefulWidget {
const SleepScoreWidget({super.key});
@override
State<SleepScoreWidget> createState() => _SleepScoreWidgetState();
}
class _SleepScoreWidgetState extends State<SleepScoreWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
List<Map<String, dynamic>> showLabel = [
{"level": 1, "name": "优秀(≥85)", "color": Color(0xFF4CAF50)},
{"level": 2, "name": "良好(75~84)", "color": Color(0xFF8BC34A)},
{"level": 3, "name": "合格(60~74)", "color": Color(0xFFFFC107)},
{"level": 4, "name": "注意(60)", "color": Color(0xFFF44336)},
];
return Container(
width: double.infinity,
// decoration: BoxDecoration(color: Colors.green),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'30天平均分',
style: TextStyle(
color: Color(0xFFD3D3D3),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'79',
style: TextStyle(
color: Colors.white,
fontSize: 48.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 56.rpx)),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(),
child: SegmentedCircleWithCenterWidget(
segments: [
SegmentData(color: Colors.red, value: 30),
SegmentData(color: Colors.green, value: 20),
SegmentData(color: Colors.blue, value: 40),
SegmentData(color: Colors.orange, value: 10),
],
strokeWidth: 8,
gapAngle: 8,
centerWidget: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"睡眠评分",
style: TextStyle(
color: stringToColor("#FFFFFF"),
fontSize:
AppConstants().normal_text_fontSize),
),
Text(
"65",
style: TextStyle(
color: stringToColor("#FF9F66"),
fontSize: 100.rpx),
),
],
),
),
),
),
),
Container(
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'睡眠等级',
style: TextStyle(
color: Color(0xFFD3D3D3),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'合格',
style: TextStyle(
color: stringToColor("#FF9F66"),
fontSize: 48.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 56.rpx)),
),
),
].divide(SizedBox(
width: 33.rpx,
)),
),
),
Wrap(
spacing: 32.rpx,
runSpacing: 20.rpx,
children: showLabel.map<Widget>((item) {
return Container(
padding: EdgeInsets.all(5.rpx),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 20.rpx,
height: 20.rpx,
decoration: BoxDecoration(
color: item["color"],
borderRadius: BorderRadius.circular(10.rpx),
),
),
SizedBox(width: 17.rpx),
Text(
item["name"],
style: TextStyle(
color: Colors.white,
fontSize: 24.rpx,
),
),
],
),
);
}).toList(),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,631 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/date/CalendarController.dart';
import 'package:vbvs_app/controller/sleep/sleep_report_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/sleep_report/component/SleepScoreWidget.dart';
class NewSleepReportPage extends StatefulWidget {
var date;
NewSleepReportPage({super.key, required this.date});
@override
State<NewSleepReportPage> createState() => _NewSleepReportPageState();
}
class _NewSleepReportPageState extends State<NewSleepReportPage> {
SleepReportController sleepReportController = Get.find();
CalendarController calendarController = Get.find();
@override
void initState() {
if (widget == null) {
widget.date = DateTime.now();
}
calendarController.selectedDate.value =
DateTime.fromMillisecondsSinceEpoch(widget.date);
sleepReportController.selectedDate.value =
DateTime.fromMillisecondsSinceEpoch(widget.date);
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 背景透明
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'健康报告'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
],
),
),
),
body: SafeArea(
top: true,
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 30.rpx, 0, 0),
child: Container(
width: double.infinity,
constraints: BoxConstraints(
minHeight: 90.rpx,
),
decoration: BoxDecoration(
color: themeController.currentColor.sc5),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 15.rpx, 30.rpx, 15.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Stack(
alignment: Alignment.bottomLeft,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
sleepReportController.model.type =
1;
sleepReportController.updateAll();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 115.rpx, // 固定宽度为 160.rpx
alignment:
Alignment.center, // 文字居中
child: Text(
'日报'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
color:
sleepReportController
.model
.type ==
1
? themeController
.currentColor
.sc2
: themeController
.currentColor
.sc3,
),
),
),
SizedBox(height: 10.rpx),
],
),
);
}),
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
sleepReportController.model.type =
2;
sleepReportController.updateAll();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 115.rpx, // 固定宽度为 160.rpx
alignment:
Alignment.center, // 文字居中
child: Text(
'周报'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
color:
sleepReportController
.model
.type ==
2
? themeController
.currentColor
.sc2
: themeController
.currentColor
.sc3,
),
),
),
SizedBox(height: 10.rpx),
],
),
);
}),
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
sleepReportController.model.type =
3;
sleepReportController.updateAll();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 115.rpx, // 固定宽度为 160.rpx
alignment:
Alignment.center, // 文字居中
child: Text(
'月报'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
color:
sleepReportController
.model
.type ==
3
? themeController
.currentColor
.sc2
: themeController
.currentColor
.sc3,
),
),
),
SizedBox(height: 10.rpx),
],
),
);
}),
],
),
Obx(() {
double lineWidth = 115.rpx;
return AnimatedPositioned(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
bottom: 0,
left: sleepReportController.model.type ==
1
? 0
: sleepReportController.model.type ==
2
? 115.rpx
: 230.rpx,
child: Container(
width: lineWidth,
height: 4.rpx,
decoration: BoxDecoration(
color:
themeController.currentColor.sc2,
borderRadius:
BorderRadius.circular(2.rpx),
),
),
);
}),
],
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 0.rpx, 0),
child: Container(
width: 28.rpx,
height: 28.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/share.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc3,
),
),
),
],
),
),
),
),
Container(
width: double.infinity,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 57.rpx, 30.rpx, 57.rpx),
child: Obx(() {
var date = sleepReportController.selectedDate;
return getTimeWidget();
}),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 58.rpx),
child: ClickableContainer(
backgroundColor: themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc5, // 或你希望的点击水波纹颜色
borderRadius: AppConstants()
.normal_container_radius, // 如果你想加圆角可以设置 eg. 12.rpx
padding: EdgeInsets.zero,
onTap: () {
print('点击了体征卡片');
},
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.姓名'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.年龄'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'传感器1号',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'2022-02-02',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
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)),
),
),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.体重'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'1231212',
// "D11250300003",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'55kg',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
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)),
),
),
],
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 0),
child: Container(
width: double.infinity,
child: SleepScoreWidget(),
),
),
],
),
),
),
),
),
),
);
}
Widget getTimeWidget() {
if (sleepReportController.model.type == 1) {
//日报
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 28.rpx,
height: 28.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
),
Container(
child: Row(
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc3,
padding: EdgeInsets.all(10.rpx), // 增加点击热区
borderRadius: 8.rpx,
onTap: () {
sleepReportController.selectedDate.value =
sleepReportController.selectedDate.value!
.subtract(const Duration(days: 1));
calendarController.selectedDate.value =
sleepReportController.selectedDate.value;
sleepReportController.updateAll();
calendarController.updateAll();
},
child: SizedBox(
width: 9.rpx,
height: 14.rpx,
child: SvgPicture.asset(
'assets/img/icon/arrow_left.svg',
color: themeController.currentColor.sc3,
),
),
),
Container(
child: Text(
MyUtils.getFormatChineseTime(sleepReportController
.selectedDate.value!.millisecondsSinceEpoch),
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc3,
padding: EdgeInsets.all(10.rpx), // 增加点击热区
borderRadius: 8.rpx,
onTap: () {
sleepReportController.selectedDate.value =
sleepReportController.selectedDate.value!
.subtract(const Duration(days: -1));
calendarController.selectedDate.value =
sleepReportController.selectedDate.value;
sleepReportController.updateAll();
calendarController.updateAll();
},
child: SizedBox(
width: 9.rpx,
height: 14.rpx,
child: SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
color: themeController.currentColor.sc3,
),
),
),
].divide(SizedBox(
width: 26.rpx,
)),
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc3,
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx,
0.rpx,
0.rpx,
0.rpx,
),
borderRadius: 0,
onTap: () {
showSleepCalendarBottomSheet(
timestamp: sleepReportController
.selectedDate.value!.millisecondsSinceEpoch,
context: context,
onDateSelected: (selectedDate) {
print("选中日期:");
print(selectedDate);
sleepReportController.selectedDate.value = selectedDate;
calendarController.selectedDate.value = selectedDate;
sleepReportController.updateAll();
calendarController.updateAll();
});
},
child: SizedBox(
width: 28.rpx,
height: 28.rpx,
child: SvgPicture.asset(
'assets/img/icon/share.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc3,
),
),
)
],
);
}
if (sleepReportController.model.type == 2) {
//周报
}
if (sleepReportController.model.type == 3) {
//月报
}
return Container();
}
}

View File

@@ -3,8 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.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/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/device/device_type_controller.dart'; import 'package:vbvs_app/controller/device/device_type_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
@@ -26,7 +24,6 @@ class _SleepReportPageState extends State<SleepReportPage> {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find(); DeviceTypeController deviceTypeController = Get.find();
// 使用 ValueNotifier 来管理加载状态
ValueNotifier<bool> isPageLoading = ValueNotifier<bool>(true); ValueNotifier<bool> isPageLoading = ValueNotifier<bool>(true);
@override @override
@@ -121,56 +118,5 @@ class _SleepReportPageState extends State<SleepReportPage> {
); );
} }
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required double type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == 1) {
Get.toNamed("/bodyDevice");
}
if (type == 2) {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor: themeController.currentColor.sc2,
);
}
}
},
colors: [themeController.currentColor.sc17], // 背景色
child: Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.135,
constraints: BoxConstraints(
minHeight: 220.rpx,
),
padding: EdgeInsetsDirectional.fromSTEB(77.rpx, 0, 21.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFC2CED7),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Image.network(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
} }

View File

@@ -1,11 +1,8 @@
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.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/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/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';

View File

@@ -56,7 +56,7 @@ class _SettingPageState extends State<SettingPage> {
iconTheme: IconThemeData( iconTheme: IconThemeData(
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
titleSpacing: 0, titleSpacing: 0.rpx,
// leading: returnIconButtom, // leading: returnIconButtom,
title: Container( title: Container(
width: double.infinity, width: double.infinity,

View File

@@ -4,6 +4,7 @@ import 'package:EasyDartModule/EasyDartModule.dart' as edm;
import 'package:ef/ef.dart'; 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/app_uri_status.dart'; 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/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
@@ -205,12 +206,14 @@ class _UpdateUserPageState extends State<UpdateUserPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(
top: BorderSide( top: BorderSide(
color: Color(0xFFF8F5F5), color: themeController.currentColor.sc4
width: 1.rpx, .withOpacity(0.5),
width: AppConstants().border_width,
), ),
bottom: BorderSide( bottom: BorderSide(
color: Color(0xFFF8F5F5), color: themeController.currentColor.sc4
width: 1.rpx, .withOpacity(0.5),
width: AppConstants().border_width,
), ),
), ),
), ),
@@ -312,9 +315,8 @@ class _UpdateUserPageState extends State<UpdateUserPage> {
.currentColor.sc3, .currentColor.sc3,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
cursorColor: cursorColor: themeController
FlutterFlowTheme.of(context) .currentColor.sc3,
.primaryText,
), ),
), ),
), ),

View File

@@ -1,7 +1,6 @@
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/login/login_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';
import 'package:vbvs_app/pages/device/BodyDeviceWidget.dart'; import 'package:vbvs_app/pages/device/BodyDeviceWidget.dart';
@@ -30,6 +29,7 @@ import 'package:vbvs_app/pages/person/update_person_page.dart';
import 'package:vbvs_app/pages/repair/apply_repair_page.dart'; import 'package:vbvs_app/pages/repair/apply_repair_page.dart';
import 'package:vbvs_app/pages/repair/repair_list_page.dart'; import 'package:vbvs_app/pages/repair/repair_list_page.dart';
import 'package:vbvs_app/pages/setting/language_setting.dart'; import 'package:vbvs_app/pages/setting/language_setting.dart';
import 'package:vbvs_app/pages/sleep_report/new_sleep_report_page.dart';
import 'package:vbvs_app/pages/sleep_report/sleep_report_page.dart'; import 'package:vbvs_app/pages/sleep_report/sleep_report_page.dart';
import 'package:vbvs_app/pages/user/about_us_page.dart'; import 'package:vbvs_app/pages/user/about_us_page.dart';
import 'package:vbvs_app/pages/user/setting_page.dart'; import 'package:vbvs_app/pages/user/setting_page.dart';
@@ -50,7 +50,7 @@ var routes = {
"/blueteethDevice": (contxt) => BlueteethDevicePage(), "/blueteethDevice": (contxt) => BlueteethDevicePage(),
"/personPage": (contxt) => PersonPage(), "/personPage": (contxt) => PersonPage(),
"/bindDeviceSuccess": (contxt) => BindDeviceSuccess(), "/bindDeviceSuccess": (contxt) => BindDeviceSuccess(),
"/wifiPage": (contxt) => WifiPage(), "/wifiPage": (contxt, {arguments}) => WifiPage(type:arguments),
"/otherLoginPage": (contxt) => OtherLoginPage(), "/otherLoginPage": (contxt) => OtherLoginPage(),
"/updateUserPage": (contxt) => UpdateUserPage(), "/updateUserPage": (contxt) => UpdateUserPage(),
"/settingPage": (contxt) => SettingPage(), "/settingPage": (contxt) => SettingPage(),
@@ -73,6 +73,8 @@ var routes = {
"/helpPage": (contxt) => HelpPage(), "/helpPage": (contxt) => HelpPage(),
"/followPage": (contxt) => FollowPage(), "/followPage": (contxt) => FollowPage(),
"/repairListPage": (contxt) => RepairListPage(), "/repairListPage": (contxt) => RepairListPage(),
"/newSleepReportPage": (contxt, {arguments}) =>
NewSleepReportPage(date: arguments),
}; };
var onGenerateRoute = (RouteSettings settings) { var onGenerateRoute = (RouteSettings settings) {