更新分享

This commit is contained in:
wyf
2025-04-28 15:37:58 +08:00
parent 850c34b408
commit eae7a2284d
116 changed files with 12143 additions and 3017 deletions

View File

@@ -0,0 +1,803 @@
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/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/pages/device/component/DeviceDataComponentWidget.dart';
class BodyDeviceWidget extends StatefulWidget {
const BodyDeviceWidget({super.key});
@override
State<BodyDeviceWidget> createState() => _BodyDevicePageState();
}
class _BodyDevicePageState extends State<BodyDeviceWidget> {
final ThemeController themeController = Get.find();
final BodyDeviceController bodyDeviceController = Get.find();
final GlobalKey addIconKey = GlobalKey();
OverlayEntry? _popupEntry;
void _showPopup() {
final renderBox =
addIconKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox == null) return;
final position = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
double popupWidth = 190.rpx;
// 移除之前的弹窗
_popupEntry?.remove();
// 创建新的 OverlayEntry
_popupEntry = OverlayEntry(
builder: (context) => Stack(
children: [
// 半透明背景,点击后关闭弹窗
ModalBarrier(
dismissible: true,
color: Colors.transparent,
onDismiss: _hidePopup,
),
// 弹窗内容
Positioned(
top: position.dy + size.height + 26.rpx,
left: position.dx + size.width - popupWidth - 40.rpx,
child: Material(
color: Colors.transparent,
child: Container(
width: popupWidth,
padding: EdgeInsets.all(20.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(12.rpx),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 12.rpx,
spreadRadius: 2.rpx,
offset: Offset(0, 6.rpx),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 11.rpx),
ClickableContainer(
padding: EdgeInsets.symmetric(vertical: 10.rpx),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc16.withOpacity(0.1),
borderRadius: 0.rpx,
onTap: () {
print('点击扫一扫');
_hidePopup();
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor: themeController.currentColor.sc2,
);
},
child: Container(
width: double.infinity,
child: Center(
child: Text(
'扫一扫'.tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
),
),
),
SizedBox(height: 35.rpx),
ClickableContainer(
padding: EdgeInsets.symmetric(vertical: 10.rpx),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc16.withOpacity(0.1),
borderRadius: 0.rpx,
onTap: () {
_hidePopup();
Get.toNamed("/deviceType");
},
child: Container(
width: double.infinity,
child: Center(
child: Text(
'蓝牙绑定'.tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
),
),
),
SizedBox(height: 13.rpx),
],
),
),
),
),
],
),
);
// 插入新的 OverlayEntry
Overlay.of(context)!.insert(_popupEntry!);
}
void _hidePopup() {
_popupEntry?.remove();
_popupEntry = null;
}
@override
void initState() {
bodyDeviceController.keyWord.value = "";
super.initState();
bodyDeviceController.getDeviceList().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
});
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodysize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
// width: bodysize.maxWidth,
// height: bodysize.maxHeight * 1,
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: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
Positioned(
left: 0,
// child: returnIconButtom,
child: returnIconButtomAddCallback(() {
bodyDeviceController.getDeviceNum();
bodyDeviceController.getDeviceList();
bodyDeviceController.updateAll();
}),
),
Positioned(
right: 20.rpx,
child: ClickableContainer(
key: addIconKey,
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc16,
padding: EdgeInsets.all(8.rpx),
onTap: () {
// 点击图标时,展示弹窗
if (_popupEntry == null) {
_showPopup();
} else {
_hidePopup();
}
},
child: SvgPicture.asset(
'assets/img/icon/add.svg',
width: 39.rpx,
height: 39.rpx,
color: themeController.currentColor.sc16,
),
),
),
],
),
),
actions: [],
centerTitle: false,
),
body: GestureDetector(
onTap: _hidePopup, // 点击空白处自动关闭弹窗
child: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 0, 0.rpx, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
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: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Obx(() {
// return ClickableContainer(
// backgroundColor:
// Colors.transparent, // 或者你想设置的背景色
// highlightColor: themeController
// .currentColor.sc3, // 点击涟漪颜色
// borderRadius: 8.rpx, // 自定义圆角
// padding: EdgeInsets.all(
// 0), // 外部已经排版,这里不用加内边距
// onTap: () async {
// // 点击事件处理逻辑
// bodyDeviceController.model.type = 1;
// await bodyDeviceController
// .getDeviceList();
// bodyDeviceController.updateAll();
// },
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '体征检测设备.我的e护'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// color:
// bodyDeviceController
// .model
// .type ==
// 2
// ? themeController
// .currentColor
// .sc3
// : themeController
// .currentColor
// .sc2,
// ),
// ),
// SizedBox(
// width: 100.rpx,
// child: Divider(
// height: 1.rpx,
// thickness: 2.rpx,
// color: bodyDeviceController
// .model.type ==
// 2
// ? Colors.transparent
// : themeController
// .currentColor.sc2,
// ),
// ),
// ].divide(SizedBox(height: 10.rpx)),
// ),
// );
// }),
// Obx(() {
// return ClickableContainer(
// backgroundColor: Colors.transparent,
// highlightColor:
// themeController.currentColor.sc3,
// borderRadius: 8.rpx,
// padding: EdgeInsets.all(0),
// onTap: () async {
// // 这里写你的点击逻辑
// bodyDeviceController.model.type = 2;
// await bodyDeviceController
// .getDeviceList();
// bodyDeviceController.updateAll();
// },
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '体征检测设备.云关爱'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color:
// bodyDeviceController
// .model
// .type ==
// 1
// ? themeController
// .currentColor
// .sc3
// : themeController
// .currentColor
// .sc2,
// ),
// ),
// SizedBox(
// width: 100.rpx,
// child: Divider(
// height: 1.rpx,
// thickness: 2.rpx,
// color: bodyDeviceController
// .model.type ==
// 1
// ? Colors.transparent
// : themeController
// .currentColor.sc2,
// ),
// ),
// ].divide(SizedBox(height: 10.rpx)),
// ),
// );
// }),
// ].divide(SizedBox(width: 60.rpx)),
// ),
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 {
bodyDeviceController.model.type =
1;
await bodyDeviceController
.getDeviceList();
bodyDeviceController.updateAll();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width:
160.rpx, // 固定宽度为 160.rpx
alignment:
Alignment.center, // 文字居中
child: Text(
'体征检测设备.我的e护'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
color: bodyDeviceController
.model
.type ==
2
? themeController
.currentColor
.sc3
: themeController
.currentColor
.sc2,
),
),
),
SizedBox(height: 10.rpx),
],
),
);
}),
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: themeController
.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
bodyDeviceController.model.type =
2;
await bodyDeviceController
.getDeviceList();
bodyDeviceController.updateAll();
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width:
160.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: bodyDeviceController
.model
.type ==
1
? themeController
.currentColor
.sc3
: themeController
.currentColor
.sc2,
),
),
),
SizedBox(height: 10.rpx),
],
),
);
}),
],
),
Obx(() {
// 横线宽度固定为 160.rpx
double lineWidth = 160.rpx;
return AnimatedPositioned(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
bottom: 0,
left: bodyDeviceController.model.type ==
1
? 0
: 160.rpx, // 第二个按钮横线从 160.rpx 开始
child: Container(
width: lineWidth, // 横线宽度固定为 160.rpx
height: 4.rpx,
decoration: BoxDecoration(
color: themeController
.currentColor.sc2,
borderRadius:
BorderRadius.circular(2.rpx),
),
),
);
}),
],
),
Container(
width:
MediaQuery.sizeOf(context).width * 0.38,
constraints: BoxConstraints(
minWidth: 285.rpx,
),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0, 20.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
height: 80.rpx,
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: TextFormField(
onChanged: (value) {
bodyDeviceController
.keyWord.value = value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(
12.rpx, 0, 0.rpx, 0),
isDense: true,
labelStyle:
FlutterFlowTheme.of(
context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
),
hintText: '体征检测设备.输入关键词'.tr,
hintStyle: FlutterFlowTheme
.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor
.sc4),
enabledBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
errorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(
context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(
context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
filled: false,
fillColor:
FlutterFlowTheme.of(
context)
.secondaryBackground,
),
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
cursorColor:
FlutterFlowTheme.of(context)
.primaryText,
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
26.rpx, 0, 0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
height: 40.rpx,
child: VerticalDivider(
thickness: 2.rpx,
color: themeController
.currentColor.sc2,
),
),
// Text(
// '体征检测设备.搜索'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: AppConstants()
// .normal_text_fontSize,
// letterSpacing: 0.0,
// color: themeController
// .currentColor.sc2,
// ),
// ),
ClickableContainer(
backgroundColor:
Colors.transparent,
highlightColor: themeController
.currentColor.sc5,
borderRadius: 6.rpx,
padding: EdgeInsets.zero,
onTap: () async {
await bodyDeviceController
.getDeviceList(
key:
bodyDeviceController
.keyWord
.value);
bodyDeviceController
.updateAll();
},
child: Text(
'体征检测设备.搜索'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
color: themeController
.currentColor.sc2,
),
),
),
].divide(SizedBox(width: 14.rpx)),
),
),
],
),
),
),
],
),
),
),
),
Obx(() {
final isEmpty =
bodyDeviceController.deviceList.value.isEmpty;
return isEmpty
? Expanded(
child: NullDataWidget(),
)
: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 26.rpx, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: bodyDeviceController
.deviceList.value
.map((device) =>
DeviceDataComponentWidget(
device: device))
.toList()
.divide(SizedBox(height: 25.rpx)),
),
),
);
}),
],
),
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
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: TextStyle(
fontFamily: 'Inter',
color: const Color(0xFFC2CED7),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Image.asset(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_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/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
class DeviceStatusInfoWidget extends StatelessWidget {
final String title; // 标题,如“在床”
final String iconAsset; // SVG 路径,如 'assets/icons/bed.svg'
final String value; // 显示内容,如“在离床”
ThemeController themeController = Get.find();
DeviceStatusInfoWidget({
super.key,
required this.title,
required this.iconAsset,
required this.value,
});
@override
Widget build(BuildContext context) {
return ClickableContainer(
backgroundColor: themeController.currentColor.sc5,
highlightColor: themeController.currentColor.sc5,
borderRadius: AppConstants().normal_container_radius,
padding: EdgeInsets.zero,
onTap: () {
print('点击了 $title 模块');
},
child: Container(
width: MediaQuery.sizeOf(context).width * 0.32,
constraints: BoxConstraints(
minWidth: 201.rpx,
minHeight: 182.rpx,
),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(20.rpx, 29.rpx, 20.rpx, 39.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SvgPicture.asset(
iconAsset,
width: 38.rpx,
height: 38.rpx,
// colorFilter: ColorFilter.mode(
// FlutterFlowTheme.of(context).primaryText,
// BlendMode.srcIn,
// ),
),
Text(
value,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 48.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
]
.divide(SizedBox(width: 18.rpx))
.addToStart(SizedBox(width: 31.rpx)),
),
Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(height: 39.rpx)),
),
),
),
);
}
}

View File

@@ -0,0 +1,477 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:qr_flutter/qr_flutter.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/controller/device/blueteeth_bind_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/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
class DeviceDetailPage extends StatefulWidget {
var device;
DeviceDetailPage({super.key, required this.device});
@override
State<DeviceDetailPage> createState() => _DeviceDetailPageState();
}
class _DeviceDetailPageState extends State<DeviceDetailPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find();
@override
void initState() {
super.initState();
}
@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,
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0.rpx,
// leading: returnIconButtom,
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.rpx,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0.rpx,
child: returnIconButtom,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 26.rpx, 30.rpx, 0.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
50.rpx, 0.rpx, 0.rpx, 0.rpx),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.267,
height: MediaQuery.sizeOf(context).width * 0.267,
constraints: BoxConstraints(
minWidth: 200.rpx,
minHeight: 200.rpx,
),
decoration: BoxDecoration(),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.设备名称'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.MAC'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.型号'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.版本'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.网络状态'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.故障状态'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.更新状态'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'设备详情.更新时间'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc4,
),
),
),
),
]
.divide(SizedBox(height: 34.rpx))
.addToStart(SizedBox(height: 92.rpx))
.addToEnd(SizedBox(height: 97.rpx)),
),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.267,
height: MediaQuery.sizeOf(context).width * 0.267,
constraints: BoxConstraints(
minWidth: 200.rpx,
minHeight: 200.rpx,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
// child: ClipRRect(
// borderRadius: BorderRadius.circular(8.rpx),
// child: Image.network(
// 'https://picsum.photos/seed/851/600',
// width: 200.rpx,
// height: 200.rpx,
// fit: BoxFit.cover,
// ),
// ),
child: QrImageView(
data: '1234567890',
version: QrVersions.auto,
size: 200.0.rpx,
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'A35968956',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['person']['name'] ?? '未命名'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['mac'] ?? '-'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'-',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'-',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['status']['status'] == 1 ? '在线'.tr : '离线'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['status']['failure'] == 1 ? '有故障'.tr : '无故障'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['status']['upgrade'] == 1 ? '有更新'.tr : '无更新'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
Container(
height: 50.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1.rpx, 0.rpx),
child: Text(
'${widget.device['update_time'] ?? '-'.tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.rpx,
color: themeController.currentColor.sc3,
),
),
),
),
]
.divide(SizedBox(height: 34.rpx))
.addToStart(SizedBox(height: 92.rpx))
.addToEnd(SizedBox(height: 97.rpx)),
),
].divide(SizedBox(width: 34.rpx)),
),
),
),
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,505 @@
import 'dart:async';
import 'package:EasyDartModule/EasyDartModule.dart' as edm;
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/CommonVariables.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/device/blueteeth_bind_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/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/WebSocketMessage.dart';
import 'package:vbvs_app/pages/device/component/DeviceStatusInfoWidget.dart';
class InstantBodyPage extends StatefulWidget {
var personInfo;
InstantBodyPage({super.key, required this.personInfo});
@override
State<InstantBodyPage> createState() => _InstantBodyPageState();
}
class _InstantBodyPageState extends State<InstantBodyPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find();
int maxBodyMotion = 1;
String breathState = "";
String inBed = "离床".tr;
String onlineState = "离线".tr;
Timer? _onlineTimer; // 添加 Timer 引用
int bodyMotion = 0;
int breathrate = 0;
String snores = "".tr;
int heartrate = 0;
@override
void initState() {
edm.EasyDartModule.websocket.sendData(jsonEncode(WebSocketMessage(
path: "/vsbs/web/rt/marttress",
type: 1,
data: {"mac": widget.personInfo['mac']})));
_startOnlineTimer(); // 初始化时启动定时器
super.initState();
}
@override
void dispose() {
_onlineTimer?.cancel(); // 取消定时器,防止内存泄漏
edm.EasyDartModule.websocket.sendData(
jsonEncode(WebSocketMessage(path: "/vsbs/web/rt/marttress", type: 2)));
super.dispose();
}
void _startOnlineTimer() {
_onlineTimer?.cancel(); // 取消之前的定时器
_onlineTimer = Timer.periodic(Duration(seconds: 30), (timer) {
if (mounted) {
setState(() {
onlineState = "离线".tr; // 30 秒内没有接收到数据,设置为离线
});
}
});
}
@override
Widget build(BuildContext context) {
Map device = widget.personInfo;
CommonVariables.callMap["/vsbs/web/rt/marttress"] = (data) {
inBed = data["inBed"];
// 心率 呼吸 体动 呼吸暂停
if ("离床" == inBed) {
breathState = "";
data["breathRate"] = 0;
data["heartRate"] = 0;
data["bodyMotion"] = 0;
} else {
breathState = data["breathState"];
bodyMotion = data['bodyMotion'];
breathrate = data["breathRate"];
heartrate = data['heartRate'];
snores = data['snores'];
}
if (mounted) {
setState(() {
onlineState = "在线".tr; // 接收到数据,设置为在线
});
}
_startOnlineTimer(); // 重置定时器
};
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,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0.rpx,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
RichText(
text: TextSpan(
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
fontSize: 30.rpx,
letterSpacing: 0.0,
),
children: [
TextSpan(
text: '实时体征.标题'.tr,
),
TextSpan(
text: "${onlineState}",
style: TextStyle(
color: onlineState == '在线'
? themeController.currentColor.sc2
: themeController
.currentColor.sc9, // 👈 单独设置颜色
),
),
],
),
),
Positioned(
left: 0.rpx,
child: returnIconButtom,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 29.rpx, 0.rpx, 0.rpx),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 120.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(
'${device['person']['name'] ?? '未命名'.tr}',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${MyUtils.getAgeByDate(MyUtils.formatBirthdayTime(device['person']['birthday'])) ?? '未知数据'.tr}',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
].divide(SizedBox(height: 34.rpx)),
),
]
.divide(SizedBox(width: 33.rpx))
.addToStart(SizedBox(width: 37.rpx)),
),
]
.addToStart(SizedBox(height: 36.rpx))
.addToEnd(SizedBox(height: 36.rpx)),
),
),
Expanded(
flex: 1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
'实时体征.设备ID'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
Text(
'实时体征.体重'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(height: 34.rpx)),
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
// '${device['_id']??'未知数据'.tr}',
"D11250300003",
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Text(
'${device['person']['weight'] ?? '未知数据'.tr}kg',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
].divide(SizedBox(height: 34.rpx)),
),
]
.divide(SizedBox(width: 33.rpx))
.addToStart(SizedBox(width: 37.rpx)),
),
]
.addToStart(SizedBox(height: 36.rpx))
.addToEnd(SizedBox(height: 36.rpx)),
),
),
],
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
66.rpx, 0, 66.rpx, 0),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/img/body_black.gif'), // 本地图片
fit: BoxFit.cover,
),
),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "在离床".tr,
iconAsset: "assets/img/icon/bed_status.svg",
value: inBed,
),
DeviceStatusInfoWidget(
title: "体动".tr,
iconAsset: "assets/img/icon/bodymotion.svg",
value: "${bodyMotion}" ?? "未知数据".tr,
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "心率".tr,
iconAsset: "assets/img/icon/heart.svg",
value: "${heartrate}",
),
DeviceStatusInfoWidget(
title: "打鼾".tr,
iconAsset: "assets/img/icon/snore.svg",
value: '${snores}'.tr,
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DeviceStatusInfoWidget(
title: "呼吸".tr,
iconAsset: "assets/img/icon/breathe.svg",
value: '${breathrate}',
),
DeviceStatusInfoWidget(
title: "呼吸暂停".tr,
iconAsset:
"assets/img/icon/breathe_pause.svg",
value: '${breathState}',
),
],
),
].divide(SizedBox(height: 49.rpx)),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 67.rpx, 0.rpx, 0.rpx),
child: Container(
height: 40.rpx,
child: Text(
bodyMotion >= maxBodyMotion ? '请保持静止'.tr : "",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc9,
),
),
),
),
SizedBox(
height: 207.rpx,
),
ClickableContainer(
backgroundColor: Colors.transparent, // 可自定义背景色
highlightColor: Colors.white, // 点击涟漪颜色
borderRadius: 16.rpx, // 圆角大小,可按需调整
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 0.rpx, 30.rpx, 0.rpx),
onTap: () {},
child: Container(
padding: EdgeInsetsDirectional.fromSTEB(
26.rpx, 26.rpx, 26.rpx, 26.rpx),
decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .primaryBackground
// .withOpacity(0.6), // 半透明背景
borderRadius: BorderRadius.circular(16.rpx),
border: Border.all(
// 设置边框颜色和宽度
color: themeController.currentColor.sc4, // 边框颜色
width: 2.rpx, // 边框宽度
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 8.rpx, 0, 0),
child: Container(
width: 23.rpx,
height: 23.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tips.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc3,
),
),
),
Expanded(
child: Text(
'实时体征.提示'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
].divide(SizedBox(width: 23.rpx)),
),
),
),
SizedBox(
height: 26.rpx,
),
],
),
),
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,255 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:img_picker/img_picker.dart';
import 'package:mobile_scanner/mobile_scanner.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/MyUtils.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class MobileScannerTestPage extends StatefulWidget {
const MobileScannerTestPage({Key? key}) : super(key: key);
@override
State<MobileScannerTestPage> createState() => _MobileScannerTestPageState();
}
class _MobileScannerTestPageState extends State<MobileScannerTestPage>
with TickerProviderStateMixin {
String? scannedText;
bool isScanning = true;
late AnimationController _controller;
late Animation<double> _animation;
late MobileScannerController _scannerController;
BlueteethBindController blueteethBindController = Get.find();
final double scanAreaSize = 480.rpx;
@override
void initState() {
super.initState();
_scannerController = MobileScannerController();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = Tween<double>(begin: 0, end: 1).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
));
}
@override
void dispose() {
_controller.dispose();
_scannerController.dispose();
super.dispose();
}
void _onDetect(BarcodeCapture capture) {
if (!isScanning) return;
final Barcode? barcode = capture.barcodes.first;
final String? value = barcode?.rawValue;
if (value != null) {
setState(() {
scannedText = value;
isScanning = false;
if (scannedText != null && scannedText!.isNotEmpty) {
blueteethBindController.scanMac.value = scannedText!;
showConfirmDialog(
context,
Container(),
'蓝牙绑定.确定绑定提示'.tr,
onConfirm: () async {
ApiResponse response =
await blueteethBindController.bindDeviceByScan(scannedText!);
if (response.code == HttpStatusCodes.ok) {
TopSlideNotification.show(
context,
text: "蓝牙绑定.连接成功".tr,
textColor: themeController.currentColor.sc2,
);
} else {
TopSlideNotification.show(
context,
text: response.msg ?? "蓝牙绑定.连接异常".tr,
textColor: themeController.currentColor.sc9,
);
}
},
onCancel: () {
print('用户点击了取消');
// 执行取消后的处理逻辑
},
);
}
});
Future.delayed(const Duration(seconds: 2), () {
setState(() {
isScanning = true;
});
});
}
}
@override
Widget build(BuildContext context) {
return 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,
),
],
),
),
centerTitle: false,
),
body: Container(
child: Column(
children: [
Expanded(
child: Stack(
children: [
MobileScanner(
controller: _scannerController,
onDetect: _onDetect,
),
Align(
alignment: Alignment.topCenter, // 使扫描框位于顶部居中
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 219.rpx), // 向上移动扫描框
child: SizedBox(
width: scanAreaSize,
height: scanAreaSize,
child: Stack(
children: [
Container(
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
),
),
AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Positioned(
top: scanAreaSize * _animation.value,
left: 0,
right: 0,
child: Container(
height: 2,
color: themeController.currentColor.sc2,
),
);
},
),
],
),
),
),
SizedBox(height: 31.rpx),
Text(
'扫一扫.提示'.tr,
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize: 26.rpx,
),
),
],
),
),
],
),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 83.rpx),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () async {
final picker = ImagePicker();
final pickedFile =
await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
final bytes = await pickedFile.readAsBytes();
final image = await decodeImageFromList(bytes);
}
},
child: Column(
children: [
Icon(Icons.photo,
color: themeController.currentColor.sc2,
size: 60.rpx),
SizedBox(height: 10.rpx),
Text(
'扫一扫.相册'.tr,
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize: 24.rpx,
),
),
],
),
),
SizedBox(width: 80.rpx),
GestureDetector(
onTap: () {
_scannerController.toggleTorch();
},
child: Column(
children: [
Icon(Icons.flashlight_on,
color: themeController.currentColor.sc2,
size: 60.rpx),
SizedBox(height: 10.rpx),
Text(
'扫一扫.手电筒'.tr,
style: TextStyle(
color: themeController.currentColor.sc2,
fontSize: 24.rpx,
),
),
],
),
),
],
),
),
],
),
),
);
}
}

View File

@@ -200,7 +200,7 @@ class _EPageState extends State<BindDeviceSuccess> {
'assets/img/icon/share.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController.currentColor.sc3,
color: Colors.white,
),
Text(
'绑定成功.立即分享'.tr,

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter_svg/svg.dart';
@@ -14,19 +13,17 @@ import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/BleDeviceData.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/device_bind/componnet/SingleBlueteethDeviceCompoentWidget.dart';
import 'package:vbvs_app/common/util/Ble.dart' as ble;
class BlueteethDevicePage extends StatefulWidget {
int tid = -1;
BlueteethDevicePage({super.key, this.tid = -1});
@override
State<BlueteethDevicePage> createState() => _EPageState();
State<BlueteethDevicePage> createState() => _BlueteethDevicePageState();
}
class _EPageState extends State<BlueteethDevicePage> {
class _BlueteethDevicePageState extends State<BlueteethDevicePage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
@@ -49,6 +46,8 @@ class _EPageState extends State<BlueteethDevicePage> {
@override
void initState() {
super.initState();
blueteethBindController.model.devicelist = [];
blueteethBindController.model.betDevicelist = [];
flutterBlue = FlutterBluePlus(); // 初始化flutterBlue实例
_checkBluetoothPermission(); // 检查蓝牙权限
Get.find<BlueteethBindController>().startStatusPolling();
@@ -114,6 +113,7 @@ class _EPageState extends State<BlueteethDevicePage> {
// 开始扫描蓝牙设备
void _startScanning() async {
if (!mounted) return;
var bluetoothState = await FlutterBluePlus.isOn;
if (!bluetoothState && !_isDialogShowing) {
_isDialogShowing = true;
@@ -128,8 +128,9 @@ class _EPageState extends State<BlueteethDevicePage> {
});
await FlutterBluePlus.startScan(timeout: Duration(seconds: 10));
// await FlutterBluePlus.startScan(timeout: Duration(minutes: 30));
FlutterBluePlus.scanResults.listen((results) {
_scanSubscription = FlutterBluePlus.scanResults.listen((results) {
final signalThreshold = blueteethBindController.model.singal!;
final filteredResults = results
.where((r) =>
@@ -149,6 +150,9 @@ class _EPageState extends State<BlueteethDevicePage> {
deviceData.rssi = r.rssi;
deviceData.mac = deviceData.deviceId.replaceAll(':', '');
parsedDeviceList.add(deviceData);
if (deviceData.mac!.toLowerCase() == 'b43a45c3dfa0') {
print('匹配设备数据: ${deviceData.mac}-->sn:${deviceData.sn}');
}
} catch (e) {
print("设备数据解析失败: $e");
}
@@ -188,13 +192,15 @@ class _EPageState extends State<BlueteethDevicePage> {
// 等待扫描完成
await Future.delayed(Duration(seconds: 10));
// await Future.delayed(Duration(minutes: 30));
await FlutterBluePlus.stopScan();
setState(() {
isScanning = false;
});
print("扫描完成");
if (mounted) {
setState(() {
isScanning = false;
});
}
// print("扫描完成");
}
}
@@ -210,10 +216,13 @@ class _EPageState extends State<BlueteethDevicePage> {
// 停止扫描
void _stopScanning() {
if (isScanning) {
FlutterBluePlus.stopScan(); // 停止扫描
setState(() {
isScanning = false; // 更新扫描状态
});
FlutterBluePlus.stopScan();
_scanSubscription?.cancel(); // 取消订阅
if (mounted) {
setState(() {
isScanning = false;
});
}
}
}
@@ -222,396 +231,15 @@ class _EPageState extends State<BlueteethDevicePage> {
_timer?.cancel();
}
StreamSubscription<List<ScanResult>>? _scanSubscription; // 添加扫描订阅变量
@override
void dispose() {
super.dispose();
_stopPeriodicScan(); // 停止定时扫描
_stopScanning(); // 确保离开页面时停止扫描
}
connectToDevice(device, {int time = 5}) {
ble.connectToDevice(
{
"device": device,
'success': (ble.ConnectedDeviceProp deviceProp) {
if (deviceProp.connectedDevicePropType ==
ble.ConnectedDevicePropType.JunHe) {
currentConnectedDeviceProp = deviceProp;
deviceProp.write3OfString("blog enable");
deviceProp.write3OfString("blog rlmax=128");
Timer(const Duration(microseconds: 100), () async {
String log = "";
Function logAdd = (l) {
log += l;
};
deviceProp.receiveLogArr.add(logAdd);
deviceProp.encodeType = 1;
deviceProp.deviceType = 1;
Timer.periodic(const Duration(milliseconds: 300), (timer) async {
if (timer.tick > 20) {
ble.disconnect(currentConnectedDeviceProp);
failSelectDialog();
timer.cancel();
}
if (log.contains("GB2312") || log.contains("UTF-8")) {
timer.cancel();
if (log.contains('CHARSET:UTF-8')) {
deviceProp.encodeType = 2;
}
if (log.contains('TARGET:ESPXX')) {
deviceProp.deviceType = 2;
}
log = "";
bool isSuccess = false;
for (var i = 0; i < 4; i++) {
deviceProp.write3OfString("at+system info");
await Future.delayed(const Duration(milliseconds: 400));
RegExp regExp = RegExp(r"Target Mac:(\S*)");
RegExpMatch? regExpMatch = regExp.firstMatch(log);
if (regExpMatch != null && regExpMatch.group(1) != null) {
String? mac = regExpMatch.group(1);
if (mac?.length == 12 && mac != "000000000000") {
bindArr[2] = "$mac".toUpperCase();
}
isSuccess = true;
break;
}
}
deviceProp.receiveLogArr.remove(logAdd);
print("$bindArr");
RegExp regExp = RegExp(
r"WIFI CONNECTED INFO:SSID=([^\t\n]*)\s*,RSSI=(\S*)\s*,");
RegExpMatch? regExpMatch = regExp.firstMatch(log);
if (regExpMatch != null && log.contains("Status=connect")) {
blueteethBindController.model.connectedWifiName =
regExpMatch.group(1) ?? "";
if (int.tryParse("${regExpMatch.group(2)}") != null) {
blueteethBindController.model.connectedRssi =
int.parse("${regExpMatch.group(2)}");
}
blueteethBindController.updateAll();
}
ble.bleParse();
if (bindArr[0] != null &&
bindArr[0] != "" &&
bindArr[1] != "") {
setState(() {
currentMsg = "绑定中...";
});
blueteethBindController.bindDevice({
"tid": widget.tid,
"name": blueteethBindController.model.deviceName,
"mac": bindArr[0],
"macA": bindArr[1],
"macB": bindArr[2]
}).then((d) {
blueteethBindController.model.bindArr = bindArr;
globalController.getDeviceList();
LoadingDialog.hide();
showCustomConfirmDialog(context, "设备添加成功!",
btnName: "打开WIFI配置",
icon: ConfirmDialogIcon.success)
.then((d) {
if (d == "confirm") {
Get.offAndToNamed("/wifi", arguments: deviceProp);
}
});
}).catchError((d) {
print("$d");
currentMsg = "绑定失败: ${d.message}";
ble.disconnect(currentConnectedDeviceProp);
failSelectDialog(title: "${d.message}");
});
} else {
LoadingDialog.hide();
Get.offAndToNamed("/wifi", arguments: deviceProp);
}
} else {
deviceProp.read6();
}
});
});
} else if (deviceProp.connectedDevicePropType ==
ble.ConnectedDevicePropType.QuanShi) {
List receive = [];
Function fun = (d) {
receive.add(d);
};
deviceProp.receiveLogArr.add(fun);
List<int> head = [
255,
255,
255,
255,
1,
0,
12,
17,
];
Timer.periodic(const Duration(seconds: 1), (timer) {
if (timer.tick > 20) {
timer.cancel();
currentMsg = "错误未能获取到MAC";
failSelectDialog();
}
deviceProp.write(
Uint8List.fromList([
0xFF,
0xFF,
0xFF,
0xFF,
0x01,
0x00,
0x0C,
0x0B,
0x0F,
0x23,
0x04
]),
null,
null);
if (receive.length > 0) {
receive.forEach((data) {
if (data.length != 17) {
return;
}
bool r = true;
for (var i = 0; i < head.length; i++) {
if (head[i] != data[i]) {
r = false;
}
}
if (r == false) {
return;
}
bindArr[1] = ble.ab2str(data.sublist(9, 15)).toUpperCase();
timer.cancel();
deviceProp.receiveLogArr.remove(fun);
blueteethBindController.model.deviceName =
deviceProp.connectDevice?.advName;
ble.disconnect(deviceProp);
toFindJunhe();
});
}
});
} else {
List receive = [];
Function fun = (d) {
receive.add(d);
};
deviceProp.receiveLogArr.add(fun);
List<int> head = [255, 255, 255, 255, 0x00, 0x08, 0x40, 0x01];
Timer.periodic(const Duration(seconds: 1), (timer) {
if (timer.tick > 20) {
timer.cancel();
currentMsg = "错误未能获取到MAC";
failSelectDialog();
}
deviceProp.write(
Uint8List.fromList([
255,
255,
255,
255,
0x00,
0x03,
0x40,
0x01,
0x01,
0x00,
0x45,
0xfd
]),
null,
null);
if (receive.length > 0) {
receive.forEach((data) {
if (data.length != 17) {
return;
}
bool r = true;
for (var i = 0; i < head.length; i++) {
if (head[i] != data[i]) {
r = false;
}
}
if (r == false) {
return;
}
bindArr[1] = ble.ab2str(data.sublist(8, 14)).toUpperCase();
print("$bindArr");
timer.cancel();
deviceProp.receiveLogArr.remove(fun);
blueteethBindController.model.deviceName =
deviceProp.connectDevice?.advName;
ble.disconnect(deviceProp);
toFindJunhe();
});
}
});
}
},
'fail': (e) {
print(e);
if (time > 0) {
connectToDevice(device, time: time - 1);
} else {
currentMsg = "蓝牙无法连接上设备";
failSelectDialog(title: currentMsg);
}
}
},
);
}
isBind() {
return !(blueteethBindController.model.bindArr[1]?.length == 12);
}
failSelectDialog({String title = ""}) {
LoadingDialog.hide();
setState(() {});
showCustomConfirmAndCancelDialog(
context, title == "" ? (isBind() ? "绑定失败" : "连接失败") : title,
confirmName: "重试", cancelName: "返回")
.then((d) {
if (d == "confirm") {
if (connectDeviceCurrent != null) {
ble.bleParse();
ble.start((List d) {
setState(() {
bleDevice = d;
});
}, bleOnCall: () {
LoadingDialog.show("连接中...\n靠近设备2米内",
icon:
isBind() ? LoadingDialogIcon.ble : LoadingDialogIcon.wifi);
setState(() {
currentMsg = "连接设备中...";
});
connectToDevice(connectDeviceCurrent);
});
} else {
bleExec();
}
} else if (d == "cancel") {
Get.back();
}
});
}
bleExec() {
ble.bleParse();
connectTimer?.cancel();
int index = 0;
bool isCloseLoadingDialog = false;
isFind = false;
blueteethBindController.model.bindArr = bindArrBackup;
bindArr = ["", "", ""];
ble.start((List d) {
setState(() {
bleDevice = d;
});
if (isBind()) {
if (isCloseLoadingDialog == false &&
bleDevice.indexWhere((item) {
if (widget.tid == 1) {
return ble.isQuanShiDevice(item["name"]);
} else {
return ble.isMHTSWES(item["name"]);
}
}) !=
-1) {
isCloseLoadingDialog = true;
LoadingDialog.hide();
}
}
}, bleOnCall: () {
if (isBind()) {
LoadingDialog.show("搜索蓝牙设备中...\n请打开蓝牙开关、定位开关\n与设备距离在2米内",
icon: isBind() ? LoadingDialogIcon.ble : LoadingDialogIcon.wifi);
Timer.periodic(const Duration(seconds: 1), (t) {
if (t.tick > 15) {
t.cancel();
isCloseLoadingDialog = true;
LoadingDialog.hide();
showCustomConfirmAndCancelDialog(context, "未发现设备",
confirmName: "重试", cancelName: "返回")
.then((d) {
if (d == "confirm") {
bleExec();
} else if (d == "cancel") {
Get.back();
}
});
} else {
if (isCloseLoadingDialog == true) {
t.cancel();
}
}
});
return;
}
LoadingDialog.show(
"${isBind() ? "绑定中...\n与设备距离在2米内" : "连接中...\n请打开蓝牙开关、定位开关\n与设备距离在2米内"}",
icon: isBind() ? LoadingDialogIcon.ble : LoadingDialogIcon.wifi);
connectTimer = Timer.periodic(const Duration(seconds: 1), (t) {
index++;
if (index > 15) {
connectTimer = null;
t.cancel();
failSelectDialog();
}
var d = bleDevice;
if (d != null && d.length > 0) {
if (isBind()) {
var deviceble = d.firstWhere((item) {
bool isFF = false;
if (widget.tid == 1) {
isFF = ble.isQuanShiDevice(item["name"]);
} else {
isFF = ble.isMHTSWES(item["name"]);
}
if (isFF) {
isFF = globalController.model.deviceList.indexWhere(
(d) => d["mac"] == item["adData"]["deviceId"]) ==
-1
? true
: false;
}
return isFF;
}, orElse: () => null);
if (!isFind && deviceble != null) {
print("quanshidevice");
isFind = true;
setState(() {
currentMsg = "连接设备中...";
});
t.cancel();
connectToDevice(deviceble["device"]);
bindArr[0] = deviceble["adData"]["deviceId"];
}
} else {
var deviceble = d.firstWhere(
(item) =>
item["adData"]["deviceId"] ==
blueteethBindController.model.bindArr[1],
orElse: () => null);
if (!isFind && deviceble != null) {
print("junhedevice");
isFind = true;
t.cancel();
setState(() {
currentMsg = "连接设备中...";
});
connectToDevice(deviceble["device"]);
bindArr[1] = deviceble["adData"]["deviceId"];
}
}
}
});
});
_stopScanning(); // 停止扫描
_scanSubscription?.cancel(); // 取消扫描订阅
connectTimer?.cancel(); // 取消连接定时器
blueteethBindController.stopStatusPolling(); // 停止状态轮询
super.dispose();
}
@override
@@ -679,7 +307,7 @@ class _EPageState extends State<BlueteethDevicePage> {
padding: EdgeInsetsDirectional.fromSTEB(
0, 30.rpx, 0, 30.rpx),
child: Text(
'蓝牙绑定.扫描蓝牙设备中…'.tr,
'蓝牙绑定.扫描'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
@@ -917,42 +545,48 @@ class _EPageState extends State<BlueteethDevicePage> {
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(19.rpx, 0, 0, 0),
child: Text(
'匹配出的外围设备(${blueteethBindController.model.devicelist!.length}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
child: Obx(() {
return Text(
'匹配出的外围设备(${blueteethBindController.model.betDevicelist!.length}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
);
}),
),
),
),
Obx(() {
return Expanded(
child: Container(
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
...blueteethBindController.model.blelist!
.map((device) =>
SingleBlueteethDeviceCompoentWidget(
// device: device,
bleDevice: device,
))
.toList()
.divide(SizedBox(height: 30.rpx))
.addToEnd(SizedBox(height: 30.rpx)),
],
if (blueteethBindController
.model.betDevicelist!.isNotEmpty) {
return Expanded(
child: Container(
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
...blueteethBindController.model.blelist!
.map((device) =>
SingleBlueteethDeviceCompoentWidget(
// device: device,
bleDevice: device,
))
.toList()
.divide(SizedBox(height: 30.rpx))
.addToEnd(SizedBox(height: 30.rpx)),
],
),
),
),
),
);
);
}
return Container();
}),
].divide(SizedBox(height: 30.rpx)),
),
@@ -979,38 +613,6 @@ class _EPageState extends State<BlueteethDevicePage> {
),
);
}
toFindJunhe() {
bool isSuccess = false;
int i = 0;
Timer.periodic(const Duration(seconds: 1), (t) async {
i++;
if (isSuccess) {
return;
}
if (i > 8) {
if (!isSuccess) {
currentMsg = "错误:未找到关联设备";
failSelectDialog(title: "绑定失败:未找到关联设备");
}
t.cancel();
return;
}
bleDevice.forEach((item) {
if (isSuccess) {
return;
}
if (item['adData']['deviceId'] == bindArr[1]) {
isSuccess = true;
t.cancel();
setState(() {
currentMsg = "寻找关联设备中...";
});
connectToDevice(item["device"]);
}
});
});
}
}
BleDeviceData parseBleData(List<int> data) {

View File

@@ -75,7 +75,7 @@ class _FancyCircleCheckboxState extends State<FancyCircleCheckbox>
child: ScaleTransition(
scale: _scaleAnimation,
child: Container(
margin: EdgeInsets.all(8.rpx),
margin: EdgeInsets.all(6.rpx),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: widget.fillColor,

View File

@@ -41,7 +41,7 @@ class _SingleBlueteethDeviceCompoentWidgetState
deviceData.rssi = widget.bleDevice.rssi;
deviceData.mac = deviceData.deviceId.replaceAll(':', '');
BleDeviceData device = deviceData;
device = blueteethBindController.model.devicelist!.firstWhere(
device = blueteethBindController.model.betDevicelist!.firstWhere(
(d) => d.mac == device.mac,
orElse: () => device,
);
@@ -64,15 +64,12 @@ class _SingleBlueteethDeviceCompoentWidgetState
onConfirm: () async {
ApiResponse response =
await blueteethBindController.bindDeviceAndMAC(device);
TopSlideNotification.show(context, text: response.msg!);
if (response.code == HttpStatusCodes.ok) {
showLoadingDialog(context); // 显示 loading
BLEDevice bledevice =
BLEDevice(device: widget.bleDevice.device);
var res1 = bledevice.isConnected;
print("res1: $res1");
THapp bledevice = THapp(device: widget.bleDevice.device);
await bledevice.device.connect();
var res2 = bledevice.isConnected;
print("res2: $res2");
if (res2) {
Navigator.pop(context);
TopSlideNotification.show(
@@ -94,7 +91,7 @@ class _SingleBlueteethDeviceCompoentWidgetState
} else {
TopSlideNotification.show(
context,
text: "蓝牙绑定.连接异常".tr,
text: response.msg ?? "蓝牙绑定.连接异常".tr,
textColor: themeController.currentColor.sc9,
);
}
@@ -104,6 +101,7 @@ class _SingleBlueteethDeviceCompoentWidgetState
// 执行取消后的处理逻辑
},
);
}
} catch (e) {
Navigator.pop(context);

View File

@@ -1,11 +1,14 @@
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:loading_indicator/loading_indicator.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/FrostedDialog.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/model/BleDeviceData.dart';
@@ -248,7 +251,7 @@ void showHaveBindDialog(BuildContext context) {
);
}
void showLoadingDialog(BuildContext context) {
void showLoadingDialog(BuildContext context, {String? title}) {
ThemeController themeController = Get.find();
showDialog(
context: context,
@@ -310,7 +313,7 @@ void showLoadingDialog(BuildContext context) {
child: RichText(
text: TextSpan(children: [
TextSpan(
text: "连接中...".tr,
text: title ?? "连接中...".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
@@ -433,6 +436,30 @@ void showConfirmDialog(
mainAxisSize: MainAxisSize.min,
children: [
// 标题
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor:
themeController.currentColor.sc21, // 点击时的背景色
padding: EdgeInsets.zero, // 这里去掉外部的 padding避免影响点击范围
onTap: () {
Get.back();
},
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 33.rpx, 0, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,使用 color 设置
color: themeController.currentColor.sc3,
),
),
),
],
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
@@ -457,9 +484,10 @@ void showConfirmDialog(
children: [
CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
Get.back();
onTap: () async {
onConfirm();
// await Future.delayed(Duration(milliseconds: 300));
Get.back();
},
colors: [
themeController.currentColor.sc1,
@@ -542,3 +570,141 @@ void showConfirmDialog(
},
);
}
void showWifiDialog(
BuildContext context,
Widget widget,
String title, {
required VoidCallback onConfirm,
}) {
ThemeController themeController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
showDialog(
context: context,
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.5), // 背景模糊色
builder: (BuildContext context) {
return FrostedDialog(
blurSigma: 3.0,
child: Container(
decoration: BoxDecoration(
color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(20.0),
),
padding: EdgeInsetsDirectional.fromSTEB(64.rpx, 0, 64.rpx, 0),
child: Container(
width: double.infinity,
constraints: BoxConstraints(
maxHeight: MediaQuery.sizeOf(context).height * 0.656,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 标题
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor:
themeController.currentColor.sc21, // 点击时的背景色
padding: EdgeInsets.zero, // 这里去掉外部的 padding避免影响点击范围
onTap: () {
Get.back();
},
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 33.rpx, 0, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,使用 color 设置
color: themeController.currentColor.sc3,
),
),
),
],
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 40.rpx, 0, 0),
child: Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
),
widget,
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 58.rpx, 0, 60.rpx),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
if (blueteethBindController.model.wifiPass == null ||
blueteethBindController.model.wifiPass!.isEmpty) {
TopSlideNotification.show(
context,
text: "wifi页.密码为空".tr,
textColor: themeController.currentColor.sc9,
);
} else {
Get.back();
onConfirm();
}
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: MediaQuery.sizeOf(context).width * 0.115,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 160.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"蓝牙绑定.连接".tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
].divide(SizedBox(
width: 70.rpx,
)),
),
),
],
),
),
),
);
},
);
}

View File

@@ -0,0 +1,421 @@
import 'package:ef/ef.dart';
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/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.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/device_share_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/FancyCircleCheckbox.dart';
class DeviceSharePage extends StatefulWidget {
var device;
DeviceSharePage({super.key, required this.device});
@override
State<DeviceSharePage> createState() => _DeviceSharePageState();
}
class _DeviceSharePageState extends State<DeviceSharePage> {
DeviceShareController deviceShareController = Get.find();
@override
void initState() {
deviceShareController.msg = "".obs;
deviceShareController.code = 0.obs;
deviceShareController.account = "".obs;
super.initState();
}
@override
Widget build(BuildContext context) {
var device = widget.device;
RxBool flag1 = true.obs;
RxBool flag2 = false.obs;
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,
),
),
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,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(47.rpx, 0, 47.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 28.rpx, 0, 0),
child: Container(
width: double.infinity,
child: Text(
'要分享的设备'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 62.rpx, 0, 62.rpx),
child: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(() => FancyCircleCheckbox(
borderColor:
themeController.currentColor.sc3,
fillColor:
themeController.currentColor.sc2,
value: flag1.value,
onChanged: (value) {
flag1.value = !flag1.value;
deviceShareController.updateAll();
},
)),
Text(
'主设备'.tr +
"${device['person']?['name'] == null ? '未命名'.tr : device['person']['name']}",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color:
themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 20.rpx)),
),
// Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Obx(() => FancyCircleCheckbox(
// borderColor:
// themeController.currentColor.sc3,
// fillColor:
// themeController.currentColor.sc2,
// value: true,
// onChanged: (value) {},
// )),
// Text(
// '主设备蓝盈盈A9876451',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// color:
// themeController.currentColor.sc3,
// ),
// ),
// ].divide(SizedBox(width: 20.rpx)),
// ),
].divide(SizedBox(height: 64.rpx)),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 58.rpx, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width * 0.66,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: Color(0xFFF3EDED),
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: TextFormField(
// controller: _model.textController1,
// focusNode: _model.textFieldFocusNode1,
initialValue: deviceShareController.account.value,
onChanged: (Value) {
deviceShareController.account.value = Value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
hintText: '请输入对方手机号或邮箱'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController1Validator
// .asValidator(context),
),
),
),
),
Obx(() {
return Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 15.rpx, 0, 0),
child: Container(
width: double.infinity,
constraints: BoxConstraints(
minHeight: 30.rpx,
),
child: deviceShareController.code != 0
? Align(
alignment: AlignmentDirectional(0, 0),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
TextSpan(
text:
'${deviceShareController.code == 1 ? "邀请成功".tr : "邀请失败".tr}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: deviceShareController
.code ==
1
? themeController
.currentColor.sc2
: themeController
.currentColor.sc9,
),
),
TextSpan(
text:
'${deviceShareController.msg}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc9,
),
),
],
),
),
)
: Container(),
),
);
}),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 58.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () async {
ApiResponse apiResponse =
await deviceShareController
.shareDevice(device['mac']);
if (apiResponse.code == HttpStatusCodes.ok) {
TopSlideNotification.show(context,
text: apiResponse.msg!);
} else {
TopSlideNotification.show(context,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9);
}
},
colors: [
// 渐变色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: MediaQuery.sizeOf(context).width * 0.214,
height: MediaQuery.sizeOf(context).height * 0.037,
constraints: BoxConstraints(
minWidth: 160.rpx,
minHeight: 60.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'发送邀请'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 379.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
TopSlideNotification.show(context,
text: "待开发功能".tr);
},
colors: [
// 渐变色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: MediaQuery.sizeOf(context).width * 0.66,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'微信好友一键分享'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
],
),
),
),
),
),
),
),
);
}
}

View File

@@ -3,18 +3,21 @@ 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/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/FrostedDialog.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/device_type_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/user_info_controller.dart';
class DeviceTypePage extends StatefulWidget {
int type = 0;//0绑定设备 1.查询我的设备
DeviceTypePage({super.key,this.type = 0});
int type = 0; //0绑定设备 1.查询我的设备
DeviceTypePage({super.key, this.type = 0});
@override
State<DeviceTypePage> createState() => _EPageState();
@@ -25,10 +28,20 @@ class _EPageState extends State<DeviceTypePage> {
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find();
@override
void initState() {
super.initState();
deviceTypeController.getDeviceType().then((response) {
if (response.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: response.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
);
}
});
// 延迟到 build 完成后执行弹窗逻辑
WidgetsBinding.instance.addPostFrameCallback((_) {
if (blueteethBindController.model.read == 1 && widget.type == 0) {
@@ -349,28 +362,29 @@ class _EPageState extends State<DeviceTypePage> {
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
_buildDeviceCard(
context,
title: '设备类型.体征监测设备'.tr,
imageUrl: 'assets/img/device.png',
type: '1',
),
_buildDeviceCard(
context,
title: '设备类型.智能床/床垫'.tr,
imageUrl: 'assets/img/bed.png',
type: '2',
),
_buildDeviceCard(
context,
title: '设备类型.摄像头'.tr,
imageUrl: 'assets/img/camera.png',
type: '3',
),
]
.divide(SizedBox(height: 26.rpx))
.addToStart(SizedBox(height: 26.rpx))
.addToEnd(SizedBox(height: 26.rpx)),
// 使用 Obx 来监听 deviceTypeList 的变化
Obx(() {
return Column(
children: [
SizedBox(height: 26.rpx), // 开始的间隔
...deviceTypeController.deviceTypeList.value
.map((device) {
return Padding(
padding: EdgeInsets.only(
bottom: 26.rpx), // 添加每个设备之间的间隔
child: _buildDeviceCard(
context,
title: device['name'], // 这里假设 device 是一个 Map
imageUrl: device['image'],
type: device['type'],
),
);
}).toList(),
SizedBox(height: 26.rpx), // 结束的间隔
],
);
}),
],
),
),
),
@@ -382,16 +396,20 @@ class _EPageState extends State<DeviceTypePage> {
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
{required String title, required String imageUrl, required double type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
if (type == 1) {
Get.toNamed("/blueteethDevice");
}
if (type == '2') {
Get.toNamed("/wifiPage");
if (type == 2) {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor: themeController.currentColor.sc2,
);
}
}
},
@@ -418,8 +436,14 @@ class _EPageState extends State<DeviceTypePage> {
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Image.asset(
// child: Image.asset(
// imageUrl,
// width: 212.rpx,
// height: 168.rpx,
// ),
child: Image.network(
imageUrl,
// fit: BoxFit.cover,
width: 212.rpx,
height: 168.rpx,
),

View File

@@ -0,0 +1,192 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.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/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/device_type_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/user_info_controller.dart';
class DeviceTypeListPage extends StatefulWidget {
DeviceTypeListPage({super.key});
@override
State<DeviceTypeListPage> createState() => _DeviceTypeListPageState();
}
class _DeviceTypeListPageState extends State<DeviceTypeListPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find();
@override
void initState() {
super.initState();
deviceTypeController.getDeviceType().then((response) {
if (response.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: response.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
);
}
});
}
@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,
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'设备列表',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// 使用 Obx 来监听 deviceTypeList 的变化
Obx(() {
return Column(
children: [
SizedBox(height: 26.rpx), // 开始的间隔
...deviceTypeController.deviceTypeList.value
.map((device) {
return Padding(
padding: EdgeInsets.only(
bottom: 26.rpx), // 添加每个设备之间的间隔
child: _buildDeviceCard(
context,
title: device['name'], // 这里假设 device 是一个 Map
imageUrl: device['image'],
type: device['type'],
),
);
}).toList(),
SizedBox(height: 26.rpx), // 结束的间隔
],
);
}),
],
),
),
),
),
),
),
),
);
}
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.asset(
// imageUrl,
// width: 212.rpx,
// height: 168.rpx,
// ),
child: Image.network(
imageUrl,
// fit: BoxFit.cover,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

View File

@@ -1,23 +1,24 @@
import 'dart:async';
import 'package:easydevice/easydevice.dart';
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/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/component/tool/cmd.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/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class WifiPage extends StatefulWidget {
BLEDevice bleDevice;
WifiPage({super.key, required this.bleDevice});
WifiPage({super.key});
// WifiPage({super.key});
@override
@@ -30,18 +31,29 @@ class _WifiPageState extends State<WifiPage> {
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
ThemeController themeController = Get.find();
var lisObj;
// List<String> _logBuffer = [];
// bool _isCollecting = false;
@override
void initState() {
super.initState();
// connectedDeviceProp = widget.connectedDeviceProp;
Timer(const Duration(microseconds: 100), () {
getWifiList();
});
blueteethBindController.wifiList = [].obs;
initWifiStatusAndWifiList();
}
@override
void dispose() {
super.dispose();
if (lisObj != null) {
lisObj.cancel();
}
blueteethBindController.currentDevice!.disconnect();
}
@override
Widget build(BuildContext context) {
print("object");
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
@@ -87,11 +99,19 @@ class _WifiPageState extends State<WifiPage> {
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
Get.offAllNamed("/bindDeviceSuccess");
if (blueteethBindController.wifiStatus.value != 1) {
TopSlideNotification.show(
context,
text: "wifi页.需配网".tr,
textColor: themeController.currentColor.sc9,
);
}
Get.toNamed("/personPage");
// Get.toNamed("/bindDeviceSuccess");
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: 100.rpx,
@@ -132,41 +152,87 @@ class _WifiPageState extends State<WifiPage> {
padding:
EdgeInsetsDirectional.fromSTEB(0, 30.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF242835),
borderRadius: BorderRadius.circular(20.rpx),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"wifi页.WLAN".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().title_text_fontSize,
),
),
Text(
"wifi页.未连接".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize,
),
),
],
),
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF242835),
borderRadius: BorderRadius.circular(20.rpx),
),
),
),
child: Column(
children: [
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"wifi页.WLAN".tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
),
),
Obx(() {
return Text(
blueteethBindController
.wifiStatus.value ==
0
? "wifi页.未连接".tr
: "wifi页.已连接".tr,
style: TextStyle(
color: blueteethBindController
.wifiStatus.value ==
0
? themeController
.currentColor.sc4
: themeController
.currentColor.sc2,
fontSize: AppConstants()
.normal_text_fontSize,
),
);
}),
],
),
),
),
Obx(() {
if (blueteethBindController
.connect_wifi.value ==
null ||
blueteethBindController
.connect_wifi.value.isEmpty) {
return Container();
} else {
return Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
blueteethBindController
.connect_wifi.value['ssid'] ??
'未命名'.tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
),
),
getWifiIconByRsso(
blueteethBindController
.connect_wifi.value),
],
);
}
})
],
)),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
@@ -190,7 +256,7 @@ class _WifiPageState extends State<WifiPage> {
mainAxisSize: MainAxisSize.max,
children: [
Text(
'可用WLAN',
'可用WLAN'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
@@ -203,157 +269,436 @@ 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,
// 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(() {
final sortedList = [
...blueteethBindController.wifiList.value
]..sort((a, b) => b['rssi']
.compareTo(a['rssi'])); // 按 rssi 倒序
return Column(
mainAxisSize: MainAxisSize.max,
children: sortedList
.map((wifiItem) => ClickableContainer(
backgroundColor:
Colors.transparent,
highlightColor: themeController
.currentColor.sc3,
padding: EdgeInsets.symmetric(
vertical: 0.rpx,
horizontal: 20.rpx),
borderRadius: 16.rpx,
onTap: () {
showWifiDialog(
context,
Padding(
padding:
EdgeInsetsDirectional
.fromSTEB(
0.rpx,
41.rpx,
0.rpx,
0),
child: Container(
height: 80.rpx,
decoration:
BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius
.circular(12
.rpx), // 加圆角
),
child: Align(
alignment:
AlignmentDirectional(
-1, 0),
child: Obx(() {
return TextFormField(
onChanged:
(value) {
blueteethBindController
.model
.wifiPass =
value;
},
autofocus:
false,
obscureText:
blueteethBindController
.model
.wifiPassShow,
decoration:
InputDecoration(
isDense:
true,
labelStyle: FlutterFlowTheme.of(
context)
.labelMedium
.override(
fontFamily:
'Inter',
fontSize:
26.rpx,
letterSpacing:
0.0,
),
hintText:
'蓝牙绑定.输入wifi密码'
.tr,
hintStyle: FlutterFlowTheme.of(context).labelMedium.override(
fontFamily:
'Inter',
fontSize: 26
.rpx,
letterSpacing:
0.0,
color: themeController
.currentColor
.sc4),
enabledBorder:
OutlineInputBorder(
borderSide:
BorderSide(
color: Color(
0x00000000),
width: 1
.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedBorder:
OutlineInputBorder(
borderSide:
BorderSide(
color: Color(
0x00000000),
width: 1
.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
errorBorder:
OutlineInputBorder(
borderSide:
BorderSide(
color: FlutterFlowTheme.of(context)
.error,
width: 1
.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide:
BorderSide(
color: FlutterFlowTheme.of(context)
.error,
width: 1
.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
filled:
false,
fillColor: FlutterFlowTheme.of(
context)
.secondaryBackground,
suffixIcon:
InkWell(
onTap:
() {
blueteethBindController
.model
.wifiPassShow = !blueteethBindController.model.wifiPassShow;
blueteethBindController
.updateAll();
},
focusNode:
FocusNode(
skipTraversal: true),
child:
Icon(
blueteethBindController.model.wifiPassShow
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
size: 30
.rpx,
),
),
),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily:
'Inter',
fontSize: 26
.rpx,
letterSpacing:
0.0,
color: Colors
.black),
cursorColor:
FlutterFlowTheme.of(
context)
.primaryText,
);
})),
),
),
wifiItem['ssid'] ??
'未命名'.tr,
onConfirm: () async {
showLoadingDialog(
context); // 显示 loading
bool flag = await sendWifiSetting(
wifiItem,
blueteethBindController
.model.wifiPass!,
blueteethBindController
.currentDevice!);
Navigator.pop(context);
if (flag) {
TopSlideNotification.show(
context,
text: "wifi页.配网成功".tr,
textColor:
themeController
.currentColor
.sc2,
);
blueteethBindController
.wifiStatus.value = 1;
blueteethBindController
.updateAll();
} else {
TopSlideNotification.show(
context,
text: "wifi页.配网失败".tr,
textColor:
themeController
.currentColor
.sc9,
);
blueteethBindController
.wifiStatus.value = 0;
blueteethBindController
.updateAll();
}
});
},
child: Row(
mainAxisSize:
MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
wifiItem['ssid'] ?? '',
style: FlutterFlowTheme
.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color:
themeController
.currentColor
.sc3,
),
),
getWifiIconByRsso(wifiItem),
],
),
))
.toList()
.divide(SizedBox(height: 67.rpx)),
);
}),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 20.rpx, vertical: 10.rpx),
borderRadius: 20.rpx,
onTap: () async {
print("点击刷新");
await initWifiList();
TopSlideNotification.show(
context,
text: "获取wifi列表成功".tr,
textColor:
themeController.currentColor.sc2,
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Container(
width: 25.rpx,
height: 25.rpx,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/refresh.svg',
fit: BoxFit.cover,
color: Colors.white, // 图标固定白色
),
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)),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.arrow_back,
color: themeController.currentColor.sc3,
size: 30.rpx,
),
Text(
'刷新',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
),
Text(
'刷新',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3),
),
].divide(SizedBox(width: 26.rpx)),
.currentColor.sc3,
),
),
].divide(SizedBox(width: 26.rpx)),
),
),
].divide(SizedBox(height: 65.rpx)),
),
@@ -419,42 +764,143 @@ class _WifiPageState extends State<WifiPage> {
);
}
getWifiList({int time = 3}) {
// LoadingDialog.show("扫描WIFI列表中...", icon: LoadingDialogIcon.wifi);
void initWifiStatusAndWifiList() {
if (lisObj != null) {
lisObj!.cancel();
}
lisObj = blueteethBindController.currentDevice!.statusStream
.listen((onData) async {
if (onData.status == BleEventType.recvLineLog) {
final line = onData.val;
print("[bleee]:" + line);
}
if (onData.status == BleEventType.ready) {
showLoadingDialog(context, title: "获取wifi列表中...".tr);
bool wifiStatus =
await getWifiStatus(blueteethBindController.currentDevice!);
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 =
await getWifiList(blueteethBindController.currentDevice!);
if (wifiList.length > 0) {
Navigator.pop(context);
TopSlideNotification.show(
context,
text: "获取wifi列表成功".tr,
textColor: themeController.currentColor.sc2,
);
blueteethBindController.wifiList.value = wifiList;
blueteethBindController.updateAll();
} else {
Navigator.pop(context);
TopSlideNotification.show(
context,
text: "获取wifi列表失败".tr,
textColor: themeController.currentColor.sc9,
);
}
}
});
}
initWifiList() async {
try {
// var device = widget.bluetoothDevice;
// String log = "";
// Function logAdd = (l) {
// log += l;
// };
var wifiList = await getWifiList(blueteethBindController.currentDevice!);
print(wifiList);
if (wifiList.length > 0) {
blueteethBindController.wifiList.value = wifiList;
blueteethBindController.updateAll();
}
return wifiList;
} catch (e) {
print(e);
TopSlideNotification.show(
context,
text: "获取wifi列表失败".tr,
textColor: themeController.currentColor.sc9,
);
}
}
checkIsCalibration() {
// if (controller.model.bindArr[0] == "" ||
// controller.model.bindArr[0] == null) {
// return;
// }
// if (controller.model.bindArr[2] == "" ||
// controller.model.bindArr[2] == null) {
// return;
// }
// if (controller.model.connectedWifiName == "" ||
// controller.model.connectedWifiName == null) {
// return;
// }
showCustomConfirmAndCancelDialog(context, "是否进行设备校准?", confirmName: "去校准")
.then((d) async {
// if (d == "confirm") {
// await Get.offAndToNamed("/calibration", arguments: [
// controller.model.bindArr[1],
// controller.model.bindArr[2]
// ]);
// Get.find<GlobalController>().getDeviceList();
// }
});
getWifiIconByRsso(wifiItem) {
if (wifiItem['rssi'] >= -30) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi4.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wifi4.png",
),
);
} else if (wifiItem['rssi'] >= -45) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi3.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wifi3.png",
),
);
} else if (wifiItem['rssi'] >= -60) {
// return SvgPicture.asset(
// 'assets/img/icon/wifi2.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wifi3.png",
),
);
} else {
// return SvgPicture.asset(
// 'assets/img/icon/wifi1.svg',
// width: 25.rpx,
// height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// );
return Container(
width: 40.rpx,
height: 40.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wifi1.png",
),
);
}
}
}

View File

@@ -7,6 +7,7 @@ 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/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
@@ -168,6 +169,8 @@ class _EPageState extends State<LoginPage> {
borderRadius: AppConstants()
.button_container_radius, // 圆角半径
onTap: () {
TopSlideNotification.show(context,
text: "待开发功能".tr);
bool agree =
loginController.model.register_agree!;
if (!agree) {

View File

@@ -5,6 +5,7 @@ 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:get_storage/get_storage.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/DailyLogUtils.dart';
@@ -442,9 +443,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
return InkWell(
onTap: () async {
try {
await DailyLogUtils
.writeLog(
"点击获取验证码");
DailyLogUtils.writeLog(
"点击获取验证码");
if (countdownController
.countdown
.value !=
@@ -457,7 +457,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
.getCode(
context);
if (apiResponse.code !=
HttpStatusCodes.ok) {
HttpStatusCodes
.ok) {
TopSlideNotification
.show(
context,
@@ -551,7 +552,7 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
.button_container_radius, // 圆角半径
onTap: () async {
try {
await DailyLogUtils.writeLog("点击登录");
DailyLogUtils.writeLog("点击登录");
bool agree =
loginController.model.register_agree!;
if (!agree) {
@@ -565,7 +566,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
ApiResponse apiResponse =
await loginController
.login(context);
if (apiResponse.code != HttpStatusCodes.ok) {
if (apiResponse.code !=
HttpStatusCodes.ok) {
TopSlideNotification.show(
context,
text: apiResponse.msg!,
@@ -580,7 +582,9 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
textColor: themeController
.currentColor.sc2,
);
Get.offAllNamed('/homePage');
// Get.offAllNamed('/homePage');
Get.offAllNamed(
"/mianPageBottomChange");
}
}
} catch (e) {

View File

@@ -0,0 +1,168 @@
import 'package:ef/ef.dart';
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/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
class MessageWidgetWidget extends StatefulWidget {
const MessageWidgetWidget({super.key});
@override
State<MessageWidgetWidget> createState() => _MessageWidgetWidgetState();
}
class _MessageWidgetWidgetState extends State<MessageWidgetWidget> {
ThemeController themeController = Get.find();
@override
Widget build(BuildContext context) {
return Stack(
children: [
ClickableContainer(
backgroundColor: themeController.currentColor.sc5,
highlightColor: themeController.currentColor.sc3,
borderRadius: 20.rpx,
padding:
EdgeInsetsDirectional.fromSTEB(31.rpx, 33.rpx, 0.rpx, 33.rpx),
onTap: () {},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: double.infinity,
constraints: BoxConstraints(
minHeight: 66.rpx,
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'实时监测结果通知'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
constraints: BoxConstraints(
minWidth: 30.rpx,
maxWidth: 120.rpx,
),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildInfoItem(context, '设备ID'),
_buildInfoItem(context, '使用人员'),
_buildInfoItem(context, '消息类型'),
_buildInfoItem(context, '检测数值'),
_buildInfoItem(context, '发生时间'),
],
),
),
Container(
constraints: BoxConstraints(
minWidth: 30.rpx,
),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildValueItem(context, '设备ID'),
_buildValueItem(context, '使用人员'),
_buildValueItem(context, '消息类型'),
_buildValueItem(context, '检测数值'),
_buildValueItem(context, '发生时间'),
],
),
),
].divide(SizedBox(width: 35.rpx)),
),
],
),
),
Positioned(
bottom: 46.rpx,
right: 20.rpx,
child: Container(
width: 123.rpx,
height: 47.rpx,
child: CustomCard(
borderRadius: AppConstants().button_container_radius, // 直角
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2
], // 单色背景
enableAnimation: true, // 有点击缩放动画
enableGradient: false, // 不用渐变
onTap: () {
// 点击处理逻辑
print('处理按钮点击了');
},
child: Center(
child: Text(
'处理'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: Colors.white,
),
),
),
),
),
),
],
);
}
Widget _buildInfoItem(BuildContext context, String label) {
return Container(
constraints: BoxConstraints(
minHeight: 62.rpx,
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
label.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
);
}
Widget _buildValueItem(BuildContext context, String value) {
return Container(
constraints: BoxConstraints(
minHeight: 62.rpx,
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
value,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,9 +7,12 @@ import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.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/main_page_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/enum/LoginStatus.dart';
import 'package:vbvs_app/pages/main_bottom/e_page.dart';
import 'package:vbvs_app/pages/main_bottom/home_page.dart';
import 'package:vbvs_app/pages/main_bottom/message_page.dart';
@@ -33,7 +36,7 @@ class MainPageBottomChange extends GetView<MainPageController> {
width: size,
height: size,
),
),
),
activeIcon: Padding(
padding: EdgeInsets.only(bottom: 6.rpx),
child: isEmpty
@@ -105,15 +108,40 @@ class MainPageBottomChange extends GetView<MainPageController> {
type: BottomNavigationBarType.fixed,
currentIndex: controller.model.currentIndex,
onTap: (index) {
Future.delayed(const Duration(milliseconds: 500), () {
if (controller.model.currentIndex != 1) {
Future.delayed(const Duration(milliseconds: 100), () {
UserInfoController userInfoController = Get.find();
bool isLoggedIn = userInfoController.model.login ==
LoginStatus.LOGIN.code;
// 需要登录的页面
if ((index == 1 || index == 2) && !isLoggedIn) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor: themeController.currentColor.sc9,
);
Future.delayed(Duration(milliseconds: 50), () {
if (Get.currentRoute == '/ePage' ||
Get.currentRoute == '/messagePage') {
Get.back();
}
Future.delayed(Duration(milliseconds: 100), () {
Get.toNamed("/loginPage");
});
});
return;
}
// 已登录 或 index 是不需要登录的页面,正常跳转
if (controller.model.currentIndex != index) {
globalController.model.hideBottomNavigationBar =
false;
globalController.updateAll();
}
controller.model.currentIndex = index;
controller.updateAll();
});
controller.model.currentIndex = index;
controller.updateAll();
},
items: [
getBottomNavigationBarItem("assets/img/menu/home.svg",

View File

@@ -1,7 +1,15 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:flutter/services.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/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/message/message_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/pages/main_bottom/component/MessageWidgetWidget.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@@ -11,17 +19,209 @@ class MessagePage extends StatefulWidget {
}
class _MessagePageState extends State<MessagePage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
ThemeController themeController = Get.find();
MessageController messageController = Get.find();
@override
void initState() {
messageController.getMessageList().then((response) {
if (response.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: response.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
);
}
});
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // 这里设置你希望的颜色
statusBarIconBrightness: Brightness.light, // 状态栏图标的亮度
));
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
body: SafeArea(
top: true,
child: Text("消息"),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
toolbarHeight: 140.rpx,
titleSpacing: 0,
title: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx,
0.rpx,
0.rpx,
0.rpx,
),
child: Container(
width: double.infinity,
height: 140.rpx, // 👈 明确告诉 Flutter 高度
child: Column(
children: [
SizedBox(height: 40.rpx), // 上边距
Expanded(
child: Stack(
alignment: Alignment.bottomLeft,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
messageController.model.type = 1;
await messageController.getMessageList();
messageController.updateAll();
},
child: Container(
width: 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:
messageController
.model.type ==
2
? themeController
.currentColor.sc3
: themeController
.currentColor.sc2,
),
),
),
);
}),
Obx(() {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc3,
borderRadius: 8.rpx,
padding: EdgeInsets.all(0),
onTap: () async {
messageController.model.type = 2;
await messageController.getMessageList();
messageController.updateAll();
},
child: Container(
width: 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:
messageController
.model.type ==
1
? themeController
.currentColor.sc3
: themeController
.currentColor.sc2,
),
),
),
);
}),
],
),
Obx(() {
double lineWidth = 160.rpx;
return AnimatedPositioned(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
bottom: 0, // 👈 现在 Stack 够大,线能放得下
left: messageController.model.type == 1
? 0
: 160.rpx,
child: Container(
width: lineWidth,
height: 4.rpx,
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(2.rpx),
),
),
);
}),
],
),
),
SizedBox(height: 17.rpx), // 上边距
],
),
),
),
actions: [],
centerTitle: false,
),
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx,
0.rpx,
30.rpx,
0.rpx,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
MessageWidgetWidget(),
MessageWidgetWidget(),
MessageWidgetWidget(),
]
.divide(SizedBox(height: 30.rpx))
.addToStart(SizedBox(height: 30.rpx))
.addToEnd(SizedBox(height: 30.rpx)),
),
),
),
),
),
],
),
),
),
),
),

View File

@@ -8,9 +8,11 @@ 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/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.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/user_info_controller.dart';
import 'package:vbvs_app/enum/LoginStatus.dart';
class MinePage extends StatefulWidget {
const MinePage({super.key});
@@ -30,6 +32,7 @@ class _MinePageState extends State<MinePage> {
statusBarColor: Colors.transparent, // 这里设置你希望的颜色
statusBarIconBrightness: Brightness.light, // 状态栏图标的亮度
));
int login = userInfoController.model.login!;
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
@@ -75,18 +78,6 @@ class _MinePageState extends State<MinePage> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
SvgPicture.asset(
'assets/img/icon/earphone.svg',
width: 29.rpx,
height: 29.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController.currentColor.sc3,
),
// SvgPicture.asset(
// 'assets/img/icon/setting.svg',
// width: 29.rpx,
// height: 29.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController.currentColor.sc3,
// ),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
@@ -95,7 +86,53 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsets
.zero, // 这里去掉外部的 padding避免影响点击范围
onTap: () {
Get.toNamed("/settingPage");
if (userInfoController.model.login ==
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "待开发功能".tr,
);
} else {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
}
},
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/earphone.svg',
width: 29.rpx,
height: 29.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController.currentColor.sc3,
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsets
.zero, // 这里去掉外部的 padding避免影响点击范围
onTap: () {
if (userInfoController.model.login ==
LoginStatus.LOGIN.code) {
Get.toNamed("/settingPage");
} else {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
}
},
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
@@ -130,10 +167,25 @@ class _MinePageState extends State<MinePage> {
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.network(
'https://picsum.photos/seed/270/600',
fit: BoxFit.cover,
),
child: login == 1
? (userInfoController.model.user!
.avatar ==
null ||
userInfoController.model
.user!.avatar!.isEmpty
? Image.asset(
"assets/img/avatar.png",
fit: BoxFit.cover,
)
: Image.network(
userInfoController
.model.user!.avatar!,
fit: BoxFit.cover,
))
: Image.asset(
"assets/img/avatar.png",
fit: BoxFit.cover,
),
),
Column(
mainAxisSize: MainAxisSize.max,
@@ -141,7 +193,11 @@ class _MinePageState extends State<MinePage> {
CrossAxisAlignment.start,
children: [
Text(
'张天爱',
login == 1
? (userInfoController.model
.user!.nick_name ??
'未命名'.tr)
: "我的.未登录".tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
@@ -154,7 +210,16 @@ class _MinePageState extends State<MinePage> {
),
),
Text(
'账号135****2598',
login == 1
? (userInfoController.model
.user!.email !=
null
? userInfoController
.model.user!.email!
: MyUtils.hidePhoneNumber(
userInfoController.model
.user!.phone!))
: "我的.未登录".tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
@@ -173,7 +238,11 @@ class _MinePageState extends State<MinePage> {
CustomCard(
borderRadius: 0,
onTap: () {
Get.toNamed("/updateUserPage");
if (login == 1) {
Get.toNamed("/updateUserPage");
} else {
Get.toNamed("/loginPage");
}
},
// colors: [themeController.currentColor.sc5],
colors: [Colors.transparent],
@@ -181,7 +250,9 @@ class _MinePageState extends State<MinePage> {
mainAxisSize: MainAxisSize.max,
children: [
Text(
'我的.个人信息'.tr,
login == 1
? '我的.个人信息'.tr
: '我的.去登录'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
@@ -239,7 +310,20 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
Get.toNamed("/deviceType",arguments:1);
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
} else {
Get.toNamed("/deviceTypeList");
}
},
child: Container(
child: Padding(
@@ -296,7 +380,25 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
} else {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor:
themeController.currentColor.sc2,
);
}
},
child: Container(
child: Padding(
@@ -353,7 +455,25 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
} else {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor:
themeController.currentColor.sc2,
);
}
},
child: Container(
child: Padding(
@@ -410,7 +530,25 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
print('点击了容器');
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
} else {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor:
themeController.currentColor.sc2,
);
}
},
child: Container(
child: Padding(
@@ -467,7 +605,25 @@ class _MinePageState extends State<MinePage> {
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
print('点击了容器');
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
} else {
TopSlideNotification.show(
context,
text: "待开发.提示".tr,
textColor:
themeController.currentColor.sc2,
);
}
},
child: Container(
child: Padding(
@@ -508,7 +664,7 @@ class _MinePageState extends State<MinePage> {
mainAxisSize: MainAxisSize.max,
children: [
Text(
'1.0.0',
'V1.0.2504.12',
style:
FlutterFlowTheme.of(context)
.bodyMedium

View File

@@ -1,31 +1,31 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
// import 'package:ef/ef.dart';
// import 'package:flutter/material.dart';
// import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
// import 'package:vbvs_app/controller/user_info_controller.dart';
class SleepReportPage extends StatefulWidget {
const SleepReportPage({super.key});
// class SleepReportPage extends StatefulWidget {
// const SleepReportPage({super.key});
@override
State<SleepReportPage> createState() => _SleepReportPageState();
}
// @override
// State<SleepReportPage> createState() => _SleepReportPageState();
// }
class _SleepReportPageState extends State<SleepReportPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
// class _SleepReportPageState extends State<SleepReportPage> {
// GlobalController globalController = Get.find();
// UserInfoController userInfoController = Get.find();
// @override
// Widget build(BuildContext context) {
// return LayoutBuilder(
// builder: (context, boxConstraints) => GestureDetector(
// onTap: () => FocusScope.of(context).unfocus(),
// child: Scaffold(
body: SafeArea(
top: true,
child: Text("睡眠报告"),
),
),
),
);
}
}
// body: SafeArea(
// top: true,
// child: Text("睡眠报告"),
// ),
// ),
// ),
// );
// }
// }

View File

@@ -1,15 +1,20 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.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/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/SelectableTagButton.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.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/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
class PersonPage extends StatefulWidget {
@@ -29,6 +34,12 @@ class _EPageState extends State<PersonPage> {
@override
void initState() {
super.initState();
personController.selectedDiseaseIds.value = [];
personController.name.value = '';
personController.gender.value = 1;
personController.birthday.value = "";
personController.weight.value = 65;
personController.dateTime = null;
}
@override
@@ -45,7 +56,7 @@ class _EPageState extends State<PersonPage> {
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
@@ -80,7 +91,17 @@ class _EPageState extends State<PersonPage> {
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
Get.offAllNamed("/bindDeviceSuccess");
ApiResponse apiRespons =
await personController.savePersonData();
if (apiRespons.code == HttpStatusCodes.ok) {
TopSlideNotification.show(context,
text: apiRespons.msg!);
Get.offAllNamed("/bindDeviceSuccess");
} else {
TopSlideNotification.show(context,
text: apiRespons.msg!,
textColor: themeController.currentColor.sc9);
}
},
colors: [
themeController.currentColor.sc1,
@@ -138,6 +159,10 @@ class _EPageState extends State<PersonPage> {
child: TextFormField(
// controller: _model.textController1,
// focusNode: _model.textFieldFocusNode1,
initialValue: personController.name.value,
onChanged: (Value) {
personController.name.value = Value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
@@ -218,69 +243,201 @@ class _EPageState extends State<PersonPage> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
Text(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: 26.rpx,
letterSpacing: 0.0,
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Container(
// width: 90.rpx,
// height: 90.rpx,
// decoration: BoxDecoration(),
// child: Container(
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// ),
// child: ColorFiltered(
// colorFilter: ColorFilter.mode(
// Colors.grey.withOpacity(
// 0.6), // 这里控制灰色度的强度
// BlendMode.saturation, // 将图像变成灰度
// ),
// child: Image.asset(
// "assets/img/man.png",
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// Text(
// '男'.tr,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(height: 14.rpx)),
// ),
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Container(
// width: 90.rpx,
// height: 90.rpx,
// decoration: BoxDecoration(),
// child: Container(
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// ),
// child: Image.asset(
// "assets/img/woman.png",
// fit: BoxFit.cover,
// ),
// ),
// ),
// Text(
// '女'.tr,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(height: 14.rpx)),
// ),
Obx(
() {
bool isMaleGreyed =
personController.gender.value ==
0; // gender == 0 时男生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
1; // 点击时将 gender 设置为 1女生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isMaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(0.6),
BlendMode.saturation)
: ColorFilter.mode(
Colors.transparent,
BlendMode.saturation),
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
),
),
].divide(SizedBox(height: 14.rpx)),
Text(
''.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: isMaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
),
),
].divide(SizedBox(height: 14.rpx)),
),
);
},
),
Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/woman.png",
fit: BoxFit.cover,
),
),
),
Text(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: 26.rpx,
letterSpacing: 0.0,
// 女性部分
Obx(
() {
bool isFemaleGreyed =
personController.gender.value ==
1; // gender == 1 时女生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
0; // 点击时将 gender 设置为 0男生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isFemaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(0.6),
BlendMode.saturation)
: ColorFilter.mode(
Colors.transparent,
BlendMode.saturation),
child: Image.asset(
"assets/img/woman.png",
fit: BoxFit.cover,
),
),
),
),
),
].divide(SizedBox(height: 14.rpx)),
Text(
''.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: isFemaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 14.rpx)),
),
);
},
),
].divide(SizedBox(width: 170.rpx)),
),
@@ -303,10 +460,12 @@ class _EPageState extends State<PersonPage> {
Future.delayed(Duration(milliseconds: 250), () {
showDateSelectionDialog(
context,
checkDate: personController.model.birthday ??
checkDate: personController.dateTime ??
DateTime.now(),
checkChange: (DateTime d) {
personController.model.birthday = d;
personController.birthday.value =
MyUtils.formatBindTime(d);
personController.dateTime = d;
personController.updateAll();
},
);
@@ -314,17 +473,16 @@ class _EPageState extends State<PersonPage> {
},
child: Center(
child: Text(
personController.model.birthday != null
? DateFormat("yyyy年MM月dd日").format(
personController.model.birthday!)
personController.dateTime != null
? DateFormat("yyyy年MM月dd日")
.format(personController.dateTime!)
: '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: personController.model.birthday !=
null
color: personController.dateTime != null
? themeController.currentColor.sc3
: themeController.currentColor.sc4,
fontSize:
@@ -350,75 +508,103 @@ class _EPageState extends State<PersonPage> {
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: TextFormField(
// controller: _model.textController3,
// focusNode: _model.textFieldFocusNode3,
autofocus: false,
obscureText: false,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
child: Stack(
alignment: Alignment.center,
children: [
// 实际输入框(输入逻辑保留)
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
initialValue:
personController.weight.value.toString(),
onChanged: (value) {
personController.weight.value =
int.tryParse(value) ?? 0;
},
autofocus: false,
obscureText: false,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.transparent, // 隐藏输入文字
letterSpacing: 0.0,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
hintText: '人员资料.体重输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color:
themeController.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
hintText: '人员资料.体重输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color: personController.model.weight !=
null
? themeController.currentColor.sc3
: themeController.currentColor.sc4,
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController3Validator
// .asValidator(context),
Obx(() {
final weight = personController.weight.value;
return weight == 0
? const SizedBox.shrink() // 不显示任何内容
: Text(
'${weight}kg',
textAlign: TextAlign.center,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
);
}),
],
),
),
),
@@ -445,14 +631,38 @@ class _EPageState extends State<PersonPage> {
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 70.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
),
),
Obx(() {
final selectedIds = personController.selectedDiseaseIds;
final diseases = personController.diseaseList;
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 70.rpx, 70.rpx, 0),
child: Wrap(
spacing: 20.rpx,
runSpacing: 20.rpx,
children: diseases.map<Widget>((disease) {
final id = disease['_id'];
final name = disease['disease_type_name'];
final isSelected = selectedIds.contains(id);
return SelectableTagButton(
label: name,
selected: isSelected,
onTap: () {
if (isSelected) {
selectedIds.remove(id);
} else {
selectedIds.add(id);
}
personController.model.read = 0;
personController.updateAll();
//切换语言
// Get.updateLocale(Locale("en", "us"));
},
);
}).toList(),
),
);
}),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 152.rpx, 0, 0),

View File

@@ -0,0 +1,774 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.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/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/SelectableTagButton.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/body_device_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/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
class UpdatePersonPage extends StatefulWidget {
const UpdatePersonPage({super.key});
@override
State<UpdatePersonPage> createState() => _UpdatePageState();
}
class _UpdatePageState extends State<UpdatePersonPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
BodyDeviceController bodyDeviceController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
personController.getDiseaseData().then((apiResponse) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: apiResponse.code != HttpStatusCodes.ok
? themeController.currentColor.sc9
: themeController.currentColor.sc2,
);
});
}
@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,
// leading: returnIconButtom,
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: returnIconButtomAddCallback(() {
bodyDeviceController.getDeviceList();
bodyDeviceController.updateAll();
}),
),
Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
ApiResponse apiRespons =
await personController.savePersonData();
if (apiRespons.code == HttpStatusCodes.ok) {
TopSlideNotification.show(context,
text: apiRespons.msg!);
} else {
TopSlideNotification.show(context,
text: apiRespons.msg!,
textColor: themeController.currentColor.sc9);
}
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 0, 16.rpx, 0),
child: Text(
'人员资料.保存'.tr,
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Inter Tight',
color: themeController.currentColor.sc3,
letterSpacing: 0.0,
),
),
),
),
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 141.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: Color(0xFFF3EDED),
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: TextFormField(
// controller: _model.textController1,
// focusNode: _model.textFieldFocusNode1,
initialValue: personController.name.value,
onChanged: (Value) {
personController.name.value = Value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
hintText: '人员资料.名字输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController1Validator
// .asValidator(context),
),
),
),
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 90.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Container(
// width: 90.rpx,
// height: 90.rpx,
// decoration: BoxDecoration(),
// child: Container(
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// ),
// child: ColorFiltered(
// colorFilter: ColorFilter.mode(
// Colors.grey.withOpacity(
// 0.6), // 这里控制灰色度的强度
// BlendMode.saturation, // 将图像变成灰度
// ),
// child: Image.asset(
// "assets/img/man.png",
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// Text(
// '男'.tr,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(height: 14.rpx)),
// ),
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Container(
// width: 90.rpx,
// height: 90.rpx,
// decoration: BoxDecoration(),
// child: Container(
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// ),
// child: Image.asset(
// "assets/img/woman.png",
// fit: BoxFit.cover,
// ),
// ),
// ),
// Text(
// '女'.tr,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(height: 14.rpx)),
// ),
Obx(
() {
bool isMaleGreyed =
personController.gender.value ==
0; // gender == 0 时男生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
1; // 点击时将 gender 设置为 1女生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isMaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(0.6),
BlendMode.saturation)
: ColorFilter.mode(
Colors.transparent,
BlendMode.saturation),
child: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: isMaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
),
),
].divide(SizedBox(height: 14.rpx)),
),
);
},
),
// 女性部分
Obx(
() {
bool isFemaleGreyed =
personController.gender.value ==
1; // gender == 1 时女生部分变灰
return GestureDetector(
onTap: () {
personController.gender.value =
0; // 点击时将 gender 设置为 0男生部分被选中
},
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 90.rpx,
height: 90.rpx,
decoration: BoxDecoration(),
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: ColorFiltered(
colorFilter: isFemaleGreyed
? ColorFilter.mode(
Colors.grey
.withOpacity(0.6),
BlendMode.saturation)
: ColorFilter.mode(
Colors.transparent,
BlendMode.saturation),
child: Image.asset(
"assets/img/woman.png",
fit: BoxFit.cover,
),
),
),
),
Text(
''.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: isFemaleGreyed
? themeController
.currentColor
.sc4
: themeController
.currentColor
.sc3,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 14.rpx)),
),
);
},
),
].divide(SizedBox(width: 170.rpx)),
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0),
child: Container(
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(color: Color(0xFFF3EDED)),
),
child: InkWell(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
Future.delayed(Duration(milliseconds: 250), () {
showDateSelectionDialog(
context,
checkDate: personController.dateTime ??
DateTime.now(),
checkChange: (DateTime d) {
personController.birthday.value =
MyUtils.formatBindTime(d);
personController.dateTime = d;
personController.updateAll();
},
);
});
},
child: Center(
child: Text(
personController.dateTime != null
? DateFormat("yyyy年MM月dd日")
.format(personController.dateTime!)
: '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: personController.dateTime != null
? themeController.currentColor.sc3
: themeController.currentColor.sc4,
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0,
),
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 18.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: Color(0xFFF3EDED),
),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Stack(
alignment: Alignment.center,
children: [
// 实际输入框(输入逻辑保留)
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
initialValue:
personController.weight.value.toString(),
onChanged: (value) {
personController.weight.value =
int.tryParse(value) ?? 0;
},
autofocus: false,
obscureText: false,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.transparent, // 隐藏输入文字
letterSpacing: 0.0,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
hintText: '人员资料.体重输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color:
themeController.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(8.rpx),
),
filled: true,
),
),
Obx(() {
final weight = personController.weight.value;
return weight == 0
? const SizedBox.shrink() // 不显示任何内容
: Text(
'${weight}kg',
textAlign: TextAlign.center,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
);
}),
],
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 117.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'人员资料.疾病标题'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Color(0xFFF3F4F5),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
),
),
),
Obx(() {
final selectedIds = personController.selectedDiseaseIds;
final diseases = personController.diseaseList;
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 70.rpx, 70.rpx, 0),
child: Wrap(
spacing: 20.rpx,
runSpacing: 20.rpx,
children: diseases.map<Widget>((disease) {
final id = disease['_id'];
final name = disease['disease_type_name'];
final isSelected = selectedIds.contains(id);
return SelectableTagButton(
label: name,
selected: isSelected,
onTap: () {
if (isSelected) {
selectedIds.remove(id);
} else {
selectedIds.add(id);
}
personController.model.read = 0;
personController.updateAll();
//切换语言
// Get.updateLocale(Locale("en", "us"));
},
);
}).toList(),
),
);
}),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 152.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.rpx),
border: Border.all(
color: Color(0xFFE9E3E3),
),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 8.rpx, 0, 0),
child: Icon(
Icons.arrow_back,
color: Color(0xFFE4EBF0),
size: 24.rpx,
),
),
Expanded(
child: Text(
'人员资料.提示'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Color(0xFFEEF3F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
].divide(SizedBox(width: 23.rpx)),
),
),
),
),
],
),
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
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.asset(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,190 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:vbvs_app/common/util/FitTool.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/component/tool/WebViewWidget.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/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
class SleepReportPage extends StatefulWidget {
var sleepUri;
SleepReportPage({super.key, required this.sleepUri});
@override
State<SleepReportPage> createState() => _SleepReportPageState();
}
class _SleepReportPageState extends State<SleepReportPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
DeviceTypeController deviceTypeController = Get.find();
@override
void initState() {
super.initState();
}
@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,
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
// leading: returnIconButtom,
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,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: InAppWebView(
key: UniqueKey(),
initialUrlRequest: URLRequest(url: WebUri(widget.sleepUri)),
),
// child: WebViewWidget(url: "${widget.sleepUri}"),
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
// child: SingleChildScrollView(
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// // 使用 Obx 来监听 deviceTypeList 的变化
// Obx(() {
// return Column(
// children: [
// SizedBox(height: 26.rpx), // 开始的间隔
// ...deviceTypeController.deviceTypeList.value
// .map((device) {
// return Padding(
// padding: EdgeInsets.only(
// bottom: 26.rpx), // 添加每个设备之间的间隔
// child: _buildDeviceCard(
// context,
// title: device['name'], // 这里假设 device 是一个 Map
// imageUrl: device['image'],
// type: device['type'],
// ),
// );
// }).toList(),
// SizedBox(height: 26.rpx), // 结束的间隔
// ],
// );
// }),
// ],
// ),
// ),
// ),
),
),
),
),
);
}
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.asset(
// imageUrl,
// width: 212.rpx,
// height: 168.rpx,
// ),
child: Image.network(
imageUrl,
// fit: BoxFit.cover,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,470 @@
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/component/tool/CustomCard.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/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
// import 'package:easydevice/easydevice.dart';
class AboutUsPage extends StatefulWidget {
const AboutUsPage({super.key});
@override
State<AboutUsPage> createState() => _AboutUsPageState();
}
class _AboutUsPageState extends State<AboutUsPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
}
@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,
// leading: returnIconButtom,
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,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 30.rpx, 25.rpx, 30.rpx, 0),
// child: Container(
// width: double.infinity,
// decoration: BoxDecoration(
// color: Color(0xFF242835),
// borderRadius: BorderRadius.circular(
// AppConstants().normal_container_radius),
// ),
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 0, 0.rpx, 0),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色
// highlightColor: themeController
// .currentColor.sc21, // 点击时的背景色
// padding: EdgeInsetsDirectional.fromSTEB(
// 40.rpx, 0.rpx, 40.rpx, 0.rpx),
// onTap: () {
// print('点击了容器');
// },
// child: Container(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 20.rpx, 0.rpx, 20.rpx),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '设置页.主题模式'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 22.rpx)),
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '深色',
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color:
// Color(0xFFD9E3EB),
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height: 15
// .rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
// ].divide(SizedBox(width: 28.rpx)),
// ),
// ],
// ),
// ),
// ),
// ),
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色
// highlightColor: themeController
// .currentColor.sc21, // 点击时的背景色
// padding: EdgeInsetsDirectional.fromSTEB(
// 40.rpx, 0.rpx, 40.rpx, 0.rpx),
// onTap: () {
// print('点击了容器');
// },
// child: Container(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 20.rpx, 0.rpx, 20.rpx),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '设置页.选择语言'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 22.rpx)),
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '中文',
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color:
// Color(0xFFD9E3EB),
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height: 15
// .rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
// ].divide(SizedBox(width: 28.rpx)),
// ),
// ],
// ),
// ),
// ),
// ),
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色
// highlightColor: themeController
// .currentColor.sc21, // 点击时的背景色
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 0.rpx, 0.rpx, 0.rpx),
// onTap: () {
// print('点击了容器');
// },
// child: Container(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 40.rpx, 20.rpx, 40.rpx, 20.rpx),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '设置页.关于我们'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 22.rpx)),
// ),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height:
// 14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// ),
// ),
// ),
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色
// highlightColor: themeController
// .currentColor.sc21, // 点击时的背景色
// padding: EdgeInsetsDirectional.fromSTEB(
// 40.rpx, 0.rpx, 40.rpx, 0.rpx),
// onTap: () {
// print('点击了容器');
// },
// child: Container(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 20.rpx, 0.rpx, 20.rpx),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '设置页.用户协议'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 22.rpx)),
// ),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height:
// 15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// ),
// ),
// ),
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色
// highlightColor: themeController
// .currentColor.sc21, // 点击时的背景色
// padding: EdgeInsetsDirectional.fromSTEB(
// 0.rpx, 0.rpx, 0.rpx, 0.rpx),
// onTap: () {
// print('点击了容器');
// },
// child: Container(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 40.rpx, 20.rpx, 40.rpx, 20.rpx),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '设置页.隐私协议'.tr,
// style:
// FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color: themeController
// .currentColor.sc3,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 22.rpx)),
// ),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height:
// 14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
// ],
// ),
// ),
// ),
// ),
// ]
// .divide(SizedBox(height: 0.rpx))
// .addToStart(SizedBox(height: 30.rpx))
// .addToEnd(SizedBox(height: 30.rpx)),
// ),
// ),
// ),
// ),
SizedBox(
height: 30.rpx,
),
Text(
"企业简介\n\n\n嘉兴太和信息技术有限公司成立于2013年是一家以传感技术、室内定位技术和人工智能技术为基础的国家高新技术企业AI非接触生命体征传感器、高精度室内外一体定位平台、AI视频分析系统、射频消融等技术成果目前已经拥有30多类知识产权证书多项专利技术处于行业领先水平。\n\n\n我司研发的“非接触式生命体征传感器”是一款基于BCG信号原理通过检测人体心脏搏动引起的微小振动的传感器系统。传感器系统通过将人体微弱的心跳、呼吸信号转换未电信号进行相关生命体征分析。该传感器可为用户提供高灵敏度和精确度检测结构适用于需要非接触式、高分辨率的监测场景。该系统的硬件、软件及生产维护均由我司自主开发和管理拥有完全自主知识产权并已申请多项国家专利可依据用户需求定制个性化方案。\n\n\n该产品置于床垫下方使用全程完全无感。采集的体征数据通过睡眠健康管理平台实时显示用户的健康状态并对每次的睡眠报告进行系统化归档管理支持长期查询。一旦用户在使用过程中出现异常情况系统可及时做出判断并反馈预警信息和建议。目前心率监测的准确度可达97%以上呼吸监测的准确度可达95%以上,其他生理指标的监测精度也显著优于同类产品。该产品主体材质均采用符合国家标准的环保材料,部分硅胶配件达到食品级安全标准。产品尺寸可根据需求进行定制,适用于单人床、双人床、婴儿床、椅子及枕头等多种场景。\n\n\n睡眠健康管理平台通过实时预警与远程管理,提升睡眠质量及慢病干预效率,助力养老院、月子中心、康复中心、智能寝具等行业降本增效,实现精准健康的科学管理。",
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3),
),
],
),
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
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.asset(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,623 @@
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/color/app_uri_status.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/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/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
class SettingPage extends StatefulWidget {
const SettingPage({super.key});
@override
State<SettingPage> createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
}
@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,
// leading: returnIconButtom,
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,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 25.rpx, 30.rpx, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF242835),
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0, 0.rpx, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
print('点击了容器');
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 20.rpx, 0.rpx, 20.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.主题模式'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'深色',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color:
Color(0xFFD9E3EB),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 15
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
].divide(SizedBox(width: 28.rpx)),
),
],
),
),
),
),
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
print('点击了容器');
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 20.rpx, 0.rpx, 20.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.选择语言'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'中文',
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color:
Color(0xFFD9E3EB),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 15
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
].divide(SizedBox(width: 28.rpx)),
),
],
),
),
),
),
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
Get.toNamed("/aboutUsPage");
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 20.rpx, 40.rpx, 20.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.关于我们'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height:
14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
print('点击了容器');
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 20.rpx, 0.rpx, 20.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.用户协议'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height:
15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 20.rpx, 40.rpx, 20.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.隐私协议'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height:
14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
]
.divide(SizedBox(height: 0.rpx))
.addToStart(SizedBox(height: 30.rpx))
.addToEnd(SizedBox(height: 30.rpx)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
100.rpx, 360.rpx, 100.rpx, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
ApiResponse apiResponse =
userInfoController.logOut();
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: apiResponse.code == HttpStatusCodes.ok
? themeController.currentColor.sc2
: themeController.currentColor.sc9,
);
if (apiResponse.code == HttpStatusCodes.ok) {
Get.offAllNamed("/mianPageBottomChange");
}
},
colors: [
themeController.currentColor.sc9,
], // 渐变色是同一个色,也可以根据需要调整
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'设置页.退出登录'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
100.rpx, 20.rpx, 100.rpx, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
TopSlideNotification.show(
context,
text: "待开发功能".tr,
);
},
colors: [
Colors.transparent,
], // 渐变色是同一个色,也可以根据需要调整
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'设置页.注销账号'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc9,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 100.rpx, 0.rpx, 0),
child: ClickableContainer(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {},
backgroundColor:
Colors.transparent, // 渐变色是同一个色,也可以根据需要调整
highlightColor: themeController.currentColor.sc5,
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0),
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'ICP备案号:浙ICP备2023000785号-1'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color:
themeController.currentColor.sc4,
fontFamily: 'Inter',
fontSize: AppConstants()
.smaller_text_fontSize,
letterSpacing: 0.0,
),
),
Text(
'Copyright © 202-2025 嘉兴太和信息技术有限责任公司 版权所有'
.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color:
themeController.currentColor.sc4,
fontFamily: 'Inter',
fontSize: AppConstants()
.smaller_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
height: 17.rpx,
))),
),
),
),
],
),
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
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.asset(
imageUrl,
width: 212.rpx,
height: 168.rpx,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,367 @@
import 'dart:io';
import 'package:EasyDartModule/EasyDartModule.dart' as edm;
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.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/FitTool.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/TopSlideNotification.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/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
class UpdateUserPage extends StatefulWidget {
const UpdateUserPage({super.key});
@override
State<UpdateUserPage> createState() => _UpdateUserPageState();
}
class _UpdateUserPageState extends State<UpdateUserPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
userInfoController.model.user!.tmpHead = null;
userInfoController.model.user!.tmpNickName = null;
userInfoController.model.user!.tmpHead =
userInfoController.model.user!.avatar;
userInfoController.model.user!.tmpNickName =
userInfoController.model.user!.nick_name;
}
@override
Widget build(BuildContext context) {
int login = userInfoController.model.login!;
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,
),
),
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,
),
Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
ApiResponse apiResponse =
await userInfoController.updateData();
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: apiResponse.code == HttpStatusCodes.ok
? themeController.currentColor.sc2
: themeController.currentColor.sc9,
);
if (apiResponse.code == HttpStatusCodes.ok) {
userInfoController.model.user!.tmpHead = null;
userInfoController.model.user!.tmpNickName = null;
await userInfoController.getUserInfo();
Get.back();
}
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 0.rpx, 16.rpx, 0.rpx),
child: Text(
'修改资料页.保存'.tr,
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Inter Tight',
color: themeController.currentColor.sc3,
letterSpacing: 0.0,
),
),
),
),
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
60.rpx, 0.rpx, 60.rpx, 0.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 76.rpx, 0.rpx, 0.rpx),
child: Container(
width: MediaQuery.sizeOf(context).width * 0.213,
height: MediaQuery.sizeOf(context).height * 0.098,
constraints: BoxConstraints(
minWidth: 160.rpx,
minHeight: 160.rpx,
),
decoration: BoxDecoration(),
child: Obx(() {
return getImageWidget(context);
})),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc2,
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 44.rpx, 0.rpx, 44.rpx),
borderRadius: 0,
onTap: () async {
edm.EasyDartModule.logger
.info("${userInfoController.model.user!}点击上传头像");
DailyLogUtils.writeLog(
"${userInfoController.model.user!}点击上传头像");
ApiResponse apiResponse =
await userInfoController.uploadImg();
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: apiResponse.code == HttpStatusCodes.ok
? themeController.currentColor.sc2
: themeController.currentColor.sc9,
);
},
child: Center(
child: Text(
'修改资料页.点击更换头像'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc2,
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 79.rpx, 0.rpx, 0.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Color(0xFFF8F5F5),
width: 1.rpx,
),
bottom: BorderSide(
color: Color(0xFFF8F5F5),
width: 1.rpx,
),
),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
width: 100.rpx,
height: 100.rpx,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: TextFormField(
initialValue: userInfoController
.model.user!.nick_name,
onChanged: (value) {
userInfoController.model.user!
.tmpNickName = value;
},
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle:
FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
),
hintText: '未命名'.tr,
hintStyle:
FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(
context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
focusedErrorBorder:
OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(
context)
.error,
width: 1.rpx,
),
borderRadius:
BorderRadius.circular(
8.rpx),
),
filled: false,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context)
.primaryText,
),
),
),
),
].divide(SizedBox(width: 27.rpx)),
),
),
],
),
),
),
],
),
),
),
),
),
),
),
);
}
Widget getImageWidget(BuildContext context) {
try {
UserInfoController controller = Get.find();
var head = controller.model.user!.tmpHead;
return Container(
width: 200.rpx,
height: 200.rpx,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: head == null || head.isEmpty
? Image.asset(
'assets/img/avatar.png',
fit: BoxFit.cover,
)
: Image.network(
head,
fit: BoxFit.cover,
),
),
);
} catch (e) {
print(e);
}
return Container();
}
}