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,67 +57,70 @@ 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(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey,
padding: EdgeInsetsDirectional.fromSTEB(
8.rpx, 8.rpx, 8.rpx, 8.rpx),
onTap: () => calendarController.previousMonth(),
child: Icon(
Icons.arrow_back_ios_new, Icons.arrow_back_ios_new,
color: const Color(0xFF6D6F73), color: const Color(0xFF6D6F73),
size: 24.rpx, size: 24.rpx,
), ),
Text( ),
'${_currentDate.year}${_currentDate.month}', Obx(() => Text(
'${calendarController.displayedMonth.value.year}${calendarController.displayedMonth.value.month}',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 30.rpx, fontSize: 30.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
), )),
Icon( 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, Icons.arrow_forward_ios,
color: const Color(0xFF6D6F73), color: const Color(0xFF6D6F73),
size: 24.rpx, size: 24.rpx,
), ),
),
], ],
), ),
), ),
), ),
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;
return Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
// Weekdays Header // Weekdays Header
@@ -192,7 +135,8 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
day, day,
style: TextStyle( style: TextStyle(
color: stringToColor("#FFFFFF"), color: stringToColor("#FFFFFF"),
fontSize: AppConstants().normal_text_fontSize, fontSize:
AppConstants().normal_text_fontSize,
), ),
), ),
), ),
@@ -200,47 +144,61 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
], ],
), ),
), ),
// 日历显示部分 // 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 &&
date.year == selectedDate.year &&
date.month == selectedDate.month &&
date.day == selectedDate.day;
return Expanded(
child: SleepdateWidget(
date: date,
isSelected: isSelected,
onTap: () {
calendarController.selectDate(date);
if (widget.onDateSelected != null) {
widget.onDateSelected!(date);
}
print(date);
Get.back();
},
), ),
); );
}).toList(), }).toList(),
); );
}).toList(), }).toList(),
), ),
SizedBox( SizedBox(height: 55.rpx),
height: 55.rpx,
),
Wrap( Wrap(
direction: Axis.horizontal, // 默认是水平排列的,可以去掉这行 spacing: 20.rpx,
spacing: 20.rpx, // 水平间距 runSpacing: 20.rpx,
runSpacing: 20.rpx, // 垂直间距
children: showLabel.map<Widget>((item) { children: showLabel.map<Widget>((item) {
return Container( return Container(
padding: EdgeInsets.all(5.rpx), // 可选,添加一点间距 padding: EdgeInsets.all(5.rpx),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, // 确保 Row 不会占满整个宽度 mainAxisSize: MainAxisSize.min,
children: [ children: [
Container( Container(
width: 20.rpx, width: 20.rpx,
height: 20.rpx, height: 20.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
color: item["color"], color: item["color"],
borderRadius: borderRadius: BorderRadius.circular(10.rpx),
BorderRadius.circular(10.rpx), // 圆形效果
), ),
), ),
SizedBox(width: 8.rpx), // 标签和文本之间的间距 SizedBox(width: 8.rpx),
Text( Text(
item["name"], item["name"],
style: TextStyle( style: TextStyle(
@@ -253,8 +211,10 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
); );
}).toList(), }).toList(),
), ),
], ],
), );
}),
), ),
), ),
], ],
@@ -262,3 +222,5 @@ class _SleepCalendarWidgetState extends State<SleepCalendarWidget> {
); );
} }
} }

View File

@@ -1,24 +1,38 @@
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(
onTap: onTap,
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.all(4.rpx),
child: Container(
width: 90.rpx, width: 90.rpx,
height: 90.rpx, height: 90.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.rpx), borderRadius: BorderRadius.circular(30.rpx),
color: isSelected ? Colors.black : Colors.transparent,
), ),
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx), padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFFDC1C1C), // 默认红色 color: Color(0xFFDC1C1C),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Align( child: Align(
@@ -34,6 +48,7 @@ class SleepdateWidget extends StatelessWidget {
), ),
), ),
), ),
),
); );
} }
} }

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;
} }

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;
@@ -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);
@@ -91,10 +81,10 @@ class PersonController extends GetControllerEx<PersonModel> {
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,
}; };

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,13 +278,20 @@ 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( child: (widget.device['code']
data: '1234567890', ?.toString()
.isNotEmpty ??
false)
? QrImageView(
data: widget.device['code'].toString(),
version: QrVersions.auto, version: QrVersions.auto,
size: 200.0.rpx, size: 200.0.rpx,
)
: Image.asset(
"assets/img/errorImg.jpeg",
fit: BoxFit.cover,
), ),
), ),
Container( Container(
@@ -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,7 +176,6 @@ 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: [
@@ -195,8 +208,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
children: [ children: [
Text( Text(
'实时体征.姓名'.tr, '实时体征.姓名'.tr,
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -208,8 +220,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
Text( Text(
'实时体征.年龄'.tr, '实时体征.年龄'.tr,
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -227,8 +238,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
children: [ children: [
Text( Text(
'${device['person']?['name'] ?? '未命名'.tr}', '${device['person']?['name'] ?? '未命名'.tr}',
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -240,8 +250,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
Text( Text(
'${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(device['person']?['birthday'])) ?? '未知数据'.tr}', '${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(device['person']?['birthday'])) ?? '未知数据'.tr}',
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -275,8 +284,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
children: [ children: [
Text( Text(
'实时体征.设备ID'.tr, '实时体征.设备ID'.tr,
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -288,8 +296,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
Text( Text(
'实时体征.体重'.tr, '实时体征.体重'.tr,
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -308,8 +315,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
Text( Text(
'${device['code'] ?? '未知数据'.tr}', '${device['code'] ?? '未知数据'.tr}',
// "D11250300003", // "D11250300003",
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -321,8 +327,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
Text( Text(
'${device['person']?['weight'] ?? '未知数据'.tr}kg', '${device['person']?['weight'] ?? '未知数据'.tr}kg',
style: style: FlutterFlowTheme.of(context)
FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -347,14 +352,28 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
), ),
), ),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
66.rpx, 0, 66.rpx, 0), 66.rpx, 0, 66.rpx, 0),
child: Container( child: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage(
// 'assets/img/body_black.gif'), // 本地图片
// fit: BoxFit.cover,
// ),
// ),
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage( image: AssetImage(
'assets/img/body_black.gif'), // 本地图片 onlineState == "离线".tr
? 'assets/img/black_body_still.jpg' // 静态图
: 'assets/img/body_black.gif', // 动图
),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@@ -366,13 +385,18 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
children: [ children: [
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "在离床".tr, title: "在离床".tr,
iconAsset: "assets/img/icon/bed_status.svg", iconAsset:
"assets/img/icon/bed_status.svg",
value: inBed, value: inBed,
), ),
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "体动".tr, title: "体动".tr,
iconAsset: "assets/img/icon/bodymotion.svg", iconAsset:
value: "${bodyMotion}" ?? "未知数据".tr, "assets/img/icon/bodymotion.svg",
value: (bodyMotion == null ||
bodyMotion == -1)
? "未知数据".tr
: "$bodyMotion",
), ),
], ],
), ),
@@ -383,7 +407,10 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "心率".tr, title: "心率".tr,
iconAsset: "assets/img/icon/heart.svg", iconAsset: "assets/img/icon/heart.svg",
value: "${heartrate}", value: (heartrate == null ||
heartrate == -1)
? "未知数据".tr
: "$heartrate",
), ),
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "打鼾".tr, title: "打鼾".tr,
@@ -398,8 +425,12 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
children: [ children: [
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "呼吸".tr, title: "呼吸".tr,
iconAsset: "assets/img/icon/breathe.svg", iconAsset:
value: '${breathrate}', "assets/img/icon/breathe.svg",
value: (breathrate == null ||
breathrate == -1)
? "未知数据".tr
: "$breathrate",
), ),
DeviceStatusInfoWidget( DeviceStatusInfoWidget(
title: "呼吸暂停".tr, title: "呼吸暂停".tr,
@@ -431,9 +462,12 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
), ),
), ),
SizedBox( // SizedBox(
height: 207.rpx, // height: 207.rpx,
// ),
],
), ),
)),
ClickableContainer( ClickableContainer(
backgroundColor: Colors.transparent, // 可自定义背景色 backgroundColor: Colors.transparent, // 可自定义背景色
highlightColor: Colors.white, // 点击涟漪颜色 highlightColor: Colors.white, // 点击涟漪颜色
@@ -450,9 +484,9 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
// .withOpacity(0.6), // 半透明背景 // .withOpacity(0.6), // 半透明背景
borderRadius: BorderRadius.circular(16.rpx), borderRadius: BorderRadius.circular(16.rpx),
border: Border.all( border: Border.all(
// 设置边框颜色和宽度 color: themeController.currentColor.sc4
color: themeController.currentColor.sc4, // 边框颜色 .withOpacity(0.5),
width: 2.rpx, // 边框宽度 width: 0.5.rpx,
), ),
), ),
child: Row( child: Row(
@@ -469,7 +503,7 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
child: SvgPicture.asset( child: SvgPicture.asset(
'assets/img/icon/tips.svg', 'assets/img/icon/tips.svg',
fit: BoxFit.cover, fit: BoxFit.cover,
color: themeController.currentColor.sc3, color: themeController.currentColor.sc4,
), ),
), ),
), ),
@@ -499,7 +533,6 @@ class _InstantBodyPageState extends State<InstantBodyPage> {
), ),
), ),
), ),
),
); );
} }
} }

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,57 +489,222 @@ 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 = BlueteethBindController blueteethBindController =
Get.find(); 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 =
Get.find();
String serviceAddress = "https://caibration.he-info.cn/";
String calibrationApi =
ServiceConstant.start_calibration;
String progressApi =
ServiceConstant.calibration_process;
String queryUrl = "$serviceAddress$calibrationApi";
requestWithLog(
logTitle: "设备校准",
method: MyHttpMethod.post,
queryUrl: ServiceConstant.start_calibration,
data: {
"deviceId":
blueteethBindController.currentDeviceMac
},
onSuccess: (res) {
final ValueNotifier<double> progressNotifier = final ValueNotifier<double> progressNotifier =
ValueNotifier<double>(0.0); ValueNotifier<double>(0.0);
final ValueNotifier<bool> failureNotifier = final ValueNotifier<bool> failureNotifier =
ValueNotifier<bool>(false); ValueNotifier<bool>(false);
Timer? pollingTimer; 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(
logTitle: "设备校准",
method: MyHttpMethod.post,
queryUrl: queryUrl,
data: data,
onSuccess: (res) {
if (!isSecondStep) {
// 保存第一次获取的 cid
String cid = res.rawResponse.data['cid'];
blueteethBindController.cid!.value = cid;
}
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;
progressNotifier.value = per;
if (!isSecondStep && per >= 100) {
// 第一步完成:仅 per >= 100
pollingTimer?.cancel();
TopSlideNotification.show(context,
text: tips);
deviceCalibrationController
.process.value = 1;
deviceCalibrationController deviceCalibrationController
.bed_calibration.value = 1; .bed_calibration.value = 1;
deviceCalibrationController.updateAll(); deviceCalibrationController.updateAll();
} }
if (deviceCalibrationController
.process.value == if (isSecondStep &&
1) { 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 deviceCalibrationController
.position_calibration.value = 1; .position_calibration.value = 1;
deviceCalibrationController
.process.value = 1;
deviceCalibrationController.complete =
true;
deviceCalibrationController.updateAll(); deviceCalibrationController.updateAll();
} }
pollingTimer?.cancel();
}
}, },
onFailure: (res) { onFailure: (res) {
pollingTimer?.cancel(); pollingTimer?.cancel();
@@ -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,6 +94,7 @@ class _WifiPageState extends State<WifiPage> {
left: 0, left: 0,
child: returnIconButtom, child: returnIconButtom,
), ),
if (widget.type == null)
Positioned( Positioned(
right: 20.rpx, right: 20.rpx,
child: CustomCard( child: CustomCard(
@@ -102,10 +106,9 @@ class _WifiPageState extends State<WifiPage> {
text: "wifi页.需配网".tr, text: "wifi页.需配网".tr,
textColor: themeController.currentColor.sc9, textColor: themeController.currentColor.sc9,
); );
} else {
Get.toNamed("/calibrationPage", arguments: 1);
} }
Get.toNamed("/calibrationPage",arguments: 1);
// Get.toNamed("/personPage");
// Get.toNamed("/bindDeviceSuccess");
}, },
colors: [ colors: [
themeController.currentColor.sc1, themeController.currentColor.sc1,
@@ -207,13 +210,16 @@ class _WifiPageState extends State<WifiPage> {
.connect_wifi.value.isEmpty) { .connect_wifi.value.isEmpty) {
return Container(); return Container();
} else { } else {
return Row( return Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 30.rpx),
child: Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceBetween, MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
blueteethBindController blueteethBindController.connect_wifi
.connect_wifi.value['ssid'] ?? .value['ssid'] ??
'未命名'.tr, '未命名'.tr,
style: TextStyle( style: TextStyle(
color: themeController color: themeController
@@ -226,6 +232,7 @@ class _WifiPageState extends State<WifiPage> {
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,9 +468,44 @@ 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 =
// await getWifiStatus(
// blueteethBindController
// .currentDevice!);
bool wifiStatus = false;
var aa = await getDeviceWifiStatus(
blueteethBindController
.currentDevice!,
20);
if (aa != null &&
aa is Map) {
wifiStatus = true;
blueteethBindController
.connect_wifi
.value = aa;
} else {
blueteethBindController
.connect_wifi
.value = {};
}
blueteethBindController
.wifiStatus
.value =
wifiStatus == true
? 1
: 0;
blueteethBindController
.wifiStatus
.value =
wifiStatus == true
? 1
: 0;
if (wifiStatus) {
Navigator.pop(context);
TopSlideNotification
.show(
context, context,
text: "wifi页.配网成功".tr, text: "wifi页.配网成功".tr,
textColor: textColor:
@@ -602,10 +514,29 @@ class _WifiPageState extends State<WifiPage> {
.sc2, .sc2,
); );
blueteethBindController blueteethBindController
.wifiStatus.value = 1; .wifiStatus
.value = 1;
blueteethBindController blueteethBindController
.updateAll(); .updateAll();
} else { } else {
Navigator.pop(context);
TopSlideNotification
.show(
context,
text: "wifi页.配网失败".tr,
textColor:
themeController
.currentColor
.sc9,
);
blueteethBindController
.wifiStatus
.value = 0;
blueteethBindController
.updateAll();
}
} 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 中没有固定颜色,可以这样设置
// 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/wifi4.png"),
),
child: Image.asset(
"assets/img/wifi4.png",
),
); );
} else if (wifiItem['rssi'] >= -45) { } else if (rssi >= -45) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi3.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/wifi3.png"),
),
child: Image.asset(
"assets/img/wifi3.png",
),
); );
} else if (wifiItem['rssi'] >= -60) { } else if (rssi >= -60) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi2.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/wifi3.png"),
),
child: Image.asset(
"assets/img/wifi3.png",
),
); );
} else { } else {
// return SvgPicture.asset(
// '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", } else {
), // RSSI 无法解析时的默认显示
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(shape: BoxShape.circle),
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});
@@ -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((_) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: apiResponse.msg!, text: apiResponse.msg ?? '',
textColor: apiResponse.code != HttpStatusCodes.ok textColor: themeController.currentColor.sc9,
? 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) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: apiResponse.msg!, text: apiResponse.msg ?? '',
textColor: apiResponse.code != HttpStatusCodes.ok textColor: themeController.currentColor.sc9,
? 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) {