更新页面

This commit is contained in:
wyf
2025-04-16 14:27:10 +08:00
parent 146462b467
commit 1765403f21
58 changed files with 7821 additions and 433 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
assets/img/google.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
assets/img/help_op.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

1
assets/img/icon/add.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37.18 37.18"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 275 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M18.59,37.18A18.59,18.59,0,1,1,37.18,18.59,18.61,18.61,0,0,1,18.59,37.18ZM18.59,2A16.59,16.59,0,1,0,35.18,18.59,16.61,16.61,0,0,0,18.59,2Z"/><path class="cls-1" d="M26.51,19.59H10.67a1,1,0,1,1,0-2H26.51a1,1,0,0,1,0,2Z"/><path class="cls-1" d="M18.59,27.51a1,1,0,0,1-1-1V10.67a1,1,0,1,1,2,0V26.51A1,1,0,0,1,18.59,27.51Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 574 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16.54 31.09"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 261 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M15.54,31.09a1,1,0,0,1-.7-.3L.29,16.25a1,1,0,0,1,0-1.41L14.84.29a1,1,0,0,1,1.41,0,1,1,0,0,1,0,1.42L2.41,15.54,16.25,29.38a1,1,0,0,1-.71,1.71Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 397 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.5 28.7"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 262 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M10.75,15.35a1,1,0,0,1-.56-.18L.44,8.5A1,1,0,1,1,1.57,6.85l9.18,6.29,8-5.47L10.19,1.83A1,1,0,0,1,9.93.44,1,1,0,0,1,11.32.17l9.75,6.68a1,1,0,0,1,.43.82,1,1,0,0,1-.43.83l-9.75,6.67A1,1,0,0,1,10.75,15.35Z"/><path class="cls-1" d="M10.75,15.35a1,1,0,0,1-1-1V1a1,1,0,0,1,2,0V14.35A1,1,0,0,1,10.75,15.35Z"/><path class="cls-1" d="M10.75,28.7a1,1,0,0,1-.56-1.83L18.73,21l-8-5.46L1.57,21.85a1,1,0,0,1-1.4-.26A1,1,0,0,1,.44,20.2l9.75-6.68a1,1,0,0,1,1.13,0l9.75,6.68a1,1,0,0,1,.43.82,1,1,0,0,1-.43.83l-9.75,6.67A1,1,0,0,1,10.75,28.7Z"/><path class="cls-1" d="M10.75,28.7a1,1,0,0,1-1-1V14.35a1,1,0,0,1,2,0V27.7A1,1,0,0,1,10.75,28.7Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 875 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 231 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M21,22a1,1,0,0,1-.71-.29l-20-20A1,1,0,0,1,1.71.29l20,20a1,1,0,0,1,0,1.42A1,1,0,0,1,21,22Z"/><path class="cls-1" d="M1,22a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l20-20a1,1,0,1,1,1.42,1.42l-20,20A1,1,0,0,1,1,22Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 454 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.69 24.87"><defs><style>.cls-1{fill:#333;}</style></defs><title>资源 233 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M10.79,21.58A10.79,10.79,0,1,1,21.58,10.79,10.8,10.8,0,0,1,10.79,21.58ZM10.79,2a8.79,8.79,0,1,0,8.79,8.79A8.8,8.8,0,0,0,10.79,2Z"/><path class="cls-1" d="M23.69,24.87a1,1,0,0,1-.71-.29l-3.29-3.29a1,1,0,0,1,0-1.41,1,1,0,0,1,1.42,0l3.29,3.28a1,1,0,0,1,0,1.42A1,1,0,0,1,23.69,24.87Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 535 B

1
assets/img/icon/scan.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26.45 26.45"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 263 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M22.73,26.45h-19A3.73,3.73,0,0,1,0,22.73V19.09a1,1,0,0,1,2,0v3.64a1.72,1.72,0,0,0,1.72,1.72h19a1.72,1.72,0,0,0,1.72-1.72V19.09a1,1,0,0,1,2,0v3.64A3.73,3.73,0,0,1,22.73,26.45Z"/><path class="cls-1" d="M25.45,8.36a1,1,0,0,1-1-1V3.72A1.72,1.72,0,0,0,22.73,2h-19A1.72,1.72,0,0,0,2,3.72V7.36a1,1,0,0,1-2,0V3.72A3.73,3.73,0,0,1,3.72,0h19a3.73,3.73,0,0,1,3.72,3.72V7.36A1,1,0,0,1,25.45,8.36Z"/><path class="cls-1" d="M25.45,14.23H1a1,1,0,0,1,0-2H25.45a1,1,0,0,1,0,2Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 715 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29.3 23.58"><defs><style>.cls-1{fill:#ff9f66;}</style></defs><title>资源 234 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M13.13,1A3.15,3.15,0,0,1,16.32.19,3.23,3.23,0,0,1,18,3a39.21,39.21,0,0,1,.17,4.88v7.76A39.47,39.47,0,0,1,18,20.56a3.27,3.27,0,0,1-1.69,2.84,3.16,3.16,0,0,1-3.2-.79,42,42,0,0,1-3.57-3.4,5.19,5.19,0,0,0-1.7-1.31,5.53,5.53,0,0,0-2.13-.28,22.42,22.42,0,0,1-2.31-.07A3.68,3.68,0,0,1,1.65,17,3.75,3.75,0,0,1,.09,14.33,12.37,12.37,0,0,1,0,12.25v-.91A12.54,12.54,0,0,1,.1,9.25,3.7,3.7,0,0,1,1.65,6.61,3.72,3.72,0,0,1,3.42,6C4,6,4.83,6,5.73,6a5.49,5.49,0,0,0,2.13-.29,5.27,5.27,0,0,0,1.7-1.3A40.45,40.45,0,0,1,13.13,1Zm7.28,5.7a1.34,1.34,0,0,1,1.88.25,8.06,8.06,0,0,1,0,9.72,1.35,1.35,0,0,1-1.87.34,1.36,1.36,0,0,1-.34-1.88l.07-.09a5.4,5.4,0,0,0,0-6.45,1.35,1.35,0,0,1,.25-1.89Z"/><path class="cls-1" d="M26.26,4.14a1.35,1.35,0,0,0-2.07,1.74.6.6,0,0,0,.08.08,8.61,8.61,0,0,1,2.34,5.83,8.59,8.59,0,0,1-2.34,5.83,1.35,1.35,0,0,0,2,1.82,11.15,11.15,0,0,0,0-15.3Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
assets/img/icon/tick.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 93.39 93.39"><defs><style>.cls-1{fill:#fff;}</style></defs><title>资源 235 </title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M89.72,28.52a46.67,46.67,0,0,0-76-14.84,46.69,46.69,0,1,0,66,66,46.73,46.73,0,0,0,10-51.19Zm-43,60A41.83,41.83,0,1,1,88.52,46.7,41.88,41.88,0,0,1,46.7,88.52Zm20.81-57.7h0a2.44,2.44,0,0,0-3.44.19L40.86,56.86,29,46.18a2.44,2.44,0,0,0-3.44.18h0a2.46,2.46,0,0,0,.18,3.45L39.37,62.07l0,0,0,0h0a2.44,2.44,0,0,0,3.44-.19L67.7,34.25A2.43,2.43,0,0,0,67.51,30.82Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 609 B

BIN
assets/img/man.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/img/mye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
assets/img/netlove.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
assets/img/tel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

BIN
assets/img/wechat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/img/woman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -14,7 +14,10 @@
"提示内容3": "3.若使用扫一扫功能,请对摄像头进行授权。", "提示内容3": "3.若使用扫一扫功能,请对摄像头进行授权。",
"扫一扫绑定": "扫一扫添加新设备", "扫一扫绑定": "扫一扫添加新设备",
"蓝牙绑定": "蓝牙搜附近的设备", "蓝牙绑定": "蓝牙搜附近的设备",
"已关联体征监测设备": "已关联体征监测设备" "已关联体征监测设备": "已关联体征监测设备",
"我的e护": "我的e护",
"云关爱": "云关爱",
"报告详情": "报告详情"
}, },
"我的": { "我的": {
"个人信息": "个人信息", "个人信息": "个人信息",
@@ -45,7 +48,30 @@
"信号":"最小信号强度", "信号":"最小信号强度",
"搜索提示":"检索设备", "搜索提示":"检索设备",
"搜索":"搜索", "搜索":"搜索",
"匹配":"匹配出的外围设备" "匹配":"匹配出的外围设备",
"信号强度":"信号强度",
"SN":"SN",
"蓝牙地址":"蓝牙地址",
"mac":"mac",
"网络":"网络",
"在线":"在线",
"离线":"离线",
"版本":"版本",
"默认设备名称":"未知设备",
"传感器":"传感器",
"可绑定":"可绑定",
"已被绑定":"已被绑定",
"双人版绑定标题":"该设备为双人版,请选择",
"绑定全部":"绑定全部",
"主设备":"主设备:",
"从设备":"从设备:",
"确定":"确定",
"取消":"取消",
"无法绑定":"无法绑定!",
"无法绑定1":"检测到该设备",
"无法绑定2":"已被绑定",
"无法绑定3":",绑定前请先进行解绑,有疑问请联系客服",
"知道了":"知道了"
}, },
"登录页":{ "登录页":{
"欢迎使用太和e护":"欢迎使用太和e护", "欢迎使用太和e护":"欢迎使用太和e护",
@@ -76,6 +102,29 @@
"分享内容":"设备绑定成功后,如需对朋友或家人共享我的睡眠情况,可以进行立即分享,分享成功后,对方即可享受查看该设备权限,可以收到该设备的睡眠报告。", "分享内容":"设备绑定成功后,如需对朋友或家人共享我的睡眠情况,可以进行立即分享,分享成功后,对方即可享受查看该设备权限,可以收到该设备的睡眠报告。",
"立即分享":"立即分享", "立即分享":"立即分享",
"返回":"返回首页 开启体验" "返回":"返回首页 开启体验"
},
"日期":{
"取消":"取消",
"确定":"确定",
"年":"年",
"月":"月",
"日":"日"
},
"wifi页":{
"标题":"WIFI配置",
"跳过":"跳过",
"WLAN":"WLAN",
"未连接":"未连接",
"已连接":"已连接",
"可用WLAN":"可用WLAN",
"刷新":"刷新"
},
"其他手机登录页":{
"输入内容":"输入手机号码/邮箱",
"输入验证码":"输入验证码",
"获取验证码":"获取验证码",
"登录":"登录"
} }
} }

View File

@@ -19,6 +19,7 @@ class AppConstants {
double text_padding_up_dowm_p = 5.rpx; //段落文字上下间距 double text_padding_up_dowm_p = 5.rpx; //段落文字上下间距
double small_text_fontSize = 20.rpx; //普通文字字号
double normal_text_fontSize = 26.rpx; //普通文字字号 double normal_text_fontSize = 26.rpx; //普通文字字号
double title_text_fontSize = 30.rpx; //标题文字字号 double title_text_fontSize = 30.rpx; //标题文字字号
} }

1100
lib/common/util/Ble.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
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/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
class SleepDataModuleWidget extends StatefulWidget {
const SleepDataModuleWidget({super.key});
@override
State<SleepDataModuleWidget> createState() => _SleepDataModuleWidgetState();
}
class _SleepDataModuleWidgetState extends State<SleepDataModuleWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
ThemeController themeController = Get.find();
return Container(
width: MediaQuery.sizeOf(context).width * 0.27,
constraints: BoxConstraints(
minWidth: 200.rpx,
),
decoration: BoxDecoration(
color: stringToColor("#313541"),
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(18.rpx, 18.rpx, 18.rpx, 22.rpx),
child: Container(
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'离床次数',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
// SizedBox(
// height: 21.rpx,
// ),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'4',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 40.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0, 0.rpx, 10.rpx),
child: Text(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants().small_text_fontSize,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
],
),
Container(
width: MediaQuery.sizeOf(context).width * 0.07,
height: MediaQuery.sizeOf(context).height * 0.014,
constraints: BoxConstraints(
minWidth: 43.rpx,
minHeight: 36.rpx,
),
decoration: BoxDecoration(),
child: FFButtonWidget(
onPressed: () {
print('Button pressed ...');
},
text: '异常',
options: FFButtonOptions(
height: 40.rpx,
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0, 0.rpx, 0),
color: stringToColor("#FF7159"),
textStyle:
FlutterFlowTheme.of(context).titleSmall.override(
fontFamily: 'Inter Tight',
color: themeController.currentColor.sc3,
letterSpacing: 0.0,
fontSize: 15.rpx,
),
elevation: 0,
borderRadius: BorderRadius.circular(8.rpx),
),
),
),
],
),
Text(
'正常值:0~2',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: AppConstants().small_text_fontSize,
letterSpacing: 0.0,
color: Colors.grey),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,136 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
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/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
class SleepDateWidget extends StatefulWidget {
const SleepDateWidget({super.key});
@override
State<SleepDateWidget> createState() => _SleepDateWidgetState();
}
class _SleepDateWidgetState extends State<SleepDateWidget> {
@override
Widget build(BuildContext context) {
ThemeController themeController = Get.find();
return ClickableContainer(
backgroundColor: Colors.transparent, // 原 BoxDecoration 为空
highlightColor:
themeController.currentColor.sc3.withOpacity(0.1), // 自定义点击波纹颜色
borderRadius: AppConstants().normal_container_radius, // 原来没设置圆角
padding: EdgeInsets.zero,
onTap: () {
print("今日评分卡片点击");
},
child: Container(
width: MediaQuery.sizeOf(context).width * 0.19,
constraints: BoxConstraints(
minWidth: 143.rpx,
),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(10.rpx, 25.rpx, 10.rpx, 22.rpx),
child: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 14.rpx),
child: Text(
'今日',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: AppConstants().title_text_fontSize,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 33.rpx),
child: Text(
'07/15',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 20.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 16.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'70',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 48.rpx,
letterSpacing: 0.0,
color: stringToColor("#00C1AA")),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 16.rpx, 0, 0.rpx),
child: Text(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants().small_text_fontSize,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
],
),
),
Container(
width: 0.2.rpx,
height: 2.4.rpx,
constraints: BoxConstraints(
minWidth: 123.rpx,
minHeight: 47.rpx,
),
child: FFButtonWidget(
onPressed: () {
print('合格按钮点击');
},
text: '合格',
options: FFButtonOptions(
height: 40.rpx,
padding:
EdgeInsetsDirectional.fromSTEB(16.rpx, 0, 16.rpx, 0),
iconPadding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0),
color: stringToColor("#00C1AA"),
textStyle:
FlutterFlowTheme.of(context).titleSmall.override(
fontFamily: 'Inter Tight',
color: Colors.white,
letterSpacing: 0.0,
),
elevation: 0,
borderRadius: BorderRadius.circular(50.rpx),
),
),
),
],
),
),
),
),
);
}
}

View File

@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
class ClickableContainer extends StatelessWidget {
final Color backgroundColor; // 容器背景色
final Color highlightColor; // 点击时背景色
final EdgeInsetsGeometry padding; // 内部间距
final VoidCallback onTap; // 点击回调
final Widget child; // 子组件
final double borderRadius; // 容器圆角可选默认为0
const ClickableContainer({
Key? key,
required this.backgroundColor,
required this.highlightColor,
required this.padding,
required this.onTap,
required this.child,
this.borderRadius = 0, // 默认无圆角
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Material(
color: Colors.transparent,
child: Ink(
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(borderRadius),
),
child: InkWell(
borderRadius: BorderRadius.circular(borderRadius),
onTap: onTap,
splashColor: highlightColor.withOpacity(0.3), // 点击时的波纹效果
child: Padding(
padding: padding,
child: child, // 内容自适应
),
),
),
),
);
}
}

View File

@@ -5,7 +5,6 @@ class CustomCard extends StatefulWidget {
final VoidCallback onTap; // 点击回调 final VoidCallback onTap; // 点击回调
final List<Color> colors; // 背景颜色列表 final List<Color> colors; // 背景颜色列表
final Widget child; // 子组件 final Widget child; // 子组件
final String title; // 标题
final bool enableAnimation; // 是否启用动画效果 final bool enableAnimation; // 是否启用动画效果
final bool enableGradient; // 是否启用渐变 final bool enableGradient; // 是否启用渐变
@@ -15,7 +14,6 @@ class CustomCard extends StatefulWidget {
required this.onTap, required this.onTap,
required this.colors, required this.colors,
required this.child, required this.child,
required this.title,
this.enableAnimation = true, // 默认启用动画效果 this.enableAnimation = true, // 默认启用动画效果
this.enableGradient = true, // 默认启用渐变效果 this.enableGradient = true, // 默认启用渐变效果
}) : super(key: key); }) : super(key: key);

View File

@@ -0,0 +1,37 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class FrostedDialog extends StatelessWidget {
final Widget child;
final double blurSigma;
final Color barrierColor;
const FrostedDialog({
super.key,
required this.child,
this.blurSigma = 5.0,
this.barrierColor = const Color.fromRGBO(0, 0, 0, 0.5),
});
@override
Widget build(BuildContext context) {
return Stack(
children: [
// 毛玻璃背景
BackdropFilter(
filter: ImageFilter.blur(sigmaX: blurSigma, sigmaY: blurSigma),
child: Container(
color: Colors.transparent,
),
),
Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
backgroundColor: Colors.transparent, // 背景透明,由 child 自己决定
child: child,
),
],
);
}
}

View File

@@ -5,7 +5,24 @@ part 'blueteeth_bind_controller.g.dart'; // 由json_serializable自动生成的
@JsonSerializable() @JsonSerializable()
class BlueteethBindModel { class BlueteethBindModel {
int read = 1;//是否不再提示教程 0 不再提示 1 需要提示 int? read = 1; //是否不再提示教程 0 不再提示 1 需要提示
double? singal = -70; //扫描信号强度
List? devicelist = []; //蓝牙扫描到的设备数据列表
List? blelist = []; //蓝牙扫描到的设备数据列表
List? wifiList = [];
List bindArr = ["", "", ""];
String connectedWifiName = "";
int connectedRssi = 0;
String deviceName = "";
bool? deviceIndex0 = true;
bool? deviceIndex1 = false;
bool? deviceIndex2 = false;
BlueteethBindModel(); BlueteethBindModel();
@@ -28,4 +45,22 @@ class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
BlueteethBindController() { BlueteethBindController() {
attr = GetModel(BlueteethBindModel()).obs; attr = GetModel(BlueteethBindModel()).obs;
} }
void updateDeviceStatus() {
// try {
// } catch (e) {
// print(e);
// EasyDartModule.logger.info("向后端请求设备绑定状态报错了:$e");
// } finally {
// EasyDartModule.logger.info("向后端请求设备绑定状态");
// }
}
Future bindDevice(d) async {
print("绑定参数:$d");
await Future.delayed(Duration(seconds: 1));
// return ApiService.request
// .post("/api/device/info/bind", data: formdata.FormData.fromMap(d));
}
} }

View File

@@ -0,0 +1,175 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
part 'login_controller.g.dart';
@JsonSerializable()
class LoginModel {
//版本id
int? loginStyle = 1; //1.密码登录 2.短信登录
String? account = '17649984946'; //账户
String? password = 'wyf123,.'; //密码
String? phone; //手机号
String? code; //验证码
String? register_code;
bool? showPd = true;
int? forceLogin = 0;
bool? isIos; //是否为ios设备
bool? isWeChatNotInstalled; //是否安装微信
bool? register_agree = false; //是否同意协议
LoginModel();
static LoginModel fromJson(Map<String, dynamic> json) =>
_$LoginModelFromJson(json);
Map<String, dynamic> toJson() => _$LoginModelToJson(this);
}
class LoginController extends GetControllerEx<LoginModel> {
// 初始化实例
// final Fluwx fluwx = Fluwx();
// 微信监听返回值
// FluwxCancelable? fluwxCancelable;
// final UserRepository repository = UserRepository();
LoginController() {
attr = GetModel(LoginModel()).obs;
}
//登录
Future<String> login(BuildContext context) async {
// return '';
String message = '';
String account = '';
String password = '';
// if (model.loginStyle == 1) {
// //账号登录
// if (model.account == null || model.account!.isEmpty) {
// message = '账户不能为空';
// showToast(message);
// return message;
// }
// if (model.password == null || model.password!.isEmpty) {
// message = '密码不能为空';
// showToast(message);
// return message;
// }
// account = model.account!;
// password = model.password!;
// }
// if (model.loginStyle == 2) {
// //账号登录
// if (model.phone == null || model.phone!.isEmpty) {
// message = '手机号不能为空';
// showToast(message);
// return message;
// }
// if (!MyUtils.isValidPhoneNumber(model.phone!)) {
// message = '请输入正确的手机号';
// showToast(message);
// return message;
// }
// if (model.code == null || model.code!.isEmpty) {
// message = '验证码不能为空';
// showToast(message);
// return message;
// }
// account = model.phone!;
// password = model.code!;
// }
// RegisterController registerController = Get.find();
// if (registerController.model.register_agree == null ||
// registerController.model.register_agree != true) {
// message = "需要同意协议";
// showToast(message);
// return message;
// }
// message = await repository.login(
// model.loginStyle!, account, password, model.forceLogin);
// model.forceLogin = 0;
return message;
}
Future<String> getCode(BuildContext context) async {
String message = "";
if (model.register_agree == null || model.register_agree != true) {
// message = "需要同意协议";
// showToast(message);
return message;
}
if (model.phone == null || model.phone!.isEmpty) {
message = "请输入手机号";
// showToast(message);
return message;
}
if (!MyUtils.isValidPhoneNumber(model.phone!)) {
message = '请输入正确的手机号';
showToast(message);
return message;
}
// message = await repository.sendRegisterCode(model.phone!);
if (message.isNotEmpty) {
showToast(message ?? "发送失败,请稍后再试!");
return "发送失败,请稍后再试!";
} else {
showToast("发送验证码成功!", color: color_success);
}
return '';
}
//微信登录
// Future<void> wxLoginSendAuth() async {
// /*
// 1、目前移动应用上微信登录只提供原生的登录方式需要用户安装微信客户端才能配合使用。
// 2、对于Android应用建议总是显示微信登录按钮当用户手机没有安装微信客户端时请引导用户下载安装微信客户端。
// 3、对于iOS应用考虑到iOS应用商店审核指南中的相关规定建议开发者接入微信登录时先检测用户手机是否已安装微信客户端
// 使用sdk中isWXAppInstalled函数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等)
// */
// if (isAndroid) {
// bool isWeChatInstalled = await fluwx.isWeChatInstalled;
// debugPrint('is wechat installed: $isWeChatInstalled');
// if (!isWeChatInstalled) {
// showToast("请先安装微信APP再使用微信登录");
// return;
// }
// }
// fluwx
// .authBy(
// which: NormalAuth(
// scope: 'snsapi_userinfo',
// state: 'wechat_sdk_zhmht_wxlogin',
// ))
// .then((data) {
// //返回true表示成功或者false表示失败这边没有意义从login_controller页面构造函数监听中去处理
// debugPrint('msg:$data');
// });
// }
//退出登录
// Future<void> logout() async {
// await repository.logout();
// }
// loginByWechatCode(String code) async {
// return await repository.loginByWechatCode(code);
// }
//注销账号
// deletedAccount() async {
// return await repository.deletedAccount();
// }
}

View File

@@ -0,0 +1,33 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'login_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
LoginModel _$LoginModelFromJson(Map<String, dynamic> json) => LoginModel()
..loginStyle = (json['loginStyle'] as num?)?.toInt()
..account = json['account'] as String?
..password = json['password'] as String?
..phone = json['phone'] as String?
..code = json['code'] as String?
..register_code = json['register_code'] as String?
..showPd = json['showPd'] as bool?
..forceLogin = (json['forceLogin'] as num?)?.toInt()
..isIos = json['isIos'] as bool?
..isWeChatNotInstalled = json['isWeChatNotInstalled'] as bool?;
Map<String, dynamic> _$LoginModelToJson(LoginModel instance) =>
<String, dynamic>{
'loginStyle': instance.loginStyle,
'account': instance.account,
'password': instance.password,
'phone': instance.phone,
'code': instance.code,
'register_code': instance.register_code,
'showPd': instance.showPd,
'forceLogin': instance.forceLogin,
'isIos': instance.isIos,
'isWeChatNotInstalled': instance.isWeChatNotInstalled,
};

View File

@@ -1,8 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
class GlobalModel { class GlobalModel {
List deviceList = []; List deviceList = [];
@@ -138,16 +140,11 @@ class GlobalController extends GetControllerEx<GlobalModel> {
deviceUpdateTimerCreated() { deviceUpdateTimerCreated() {
if (getDeviceListTimer == null) { if (getDeviceListTimer == null) {
getDeviceListTimer = Timer.periodic(const Duration(seconds: 10), (t) { getDeviceListTimer = Timer.periodic(const Duration(seconds: 10), (t) {
if (userInfoController.model.token != null) { if (userInfoController.model.token != null) {}
}
}); });
} }
} }
getDeviceGroupName(device) { getDeviceGroupName(device) {
return "${device['roomName']}/${device["deviceType"]?["name"]}/${device["name"]}"; return "${device['roomName']}/${device["deviceType"]?["name"]}/${device["name"]}";
} }
@@ -169,4 +166,49 @@ class GlobalController extends GetControllerEx<GlobalModel> {
model.deviceType = rs.where((d) => d["page"] != null).toList(); model.deviceType = rs.where((d) => d["page"] != null).toList();
updateAll(); updateAll();
} }
getDeviceList({int time = 1}) async {
await EasyDartModule.dio.get("/api/device/info/list").then((d) {
Map d_ = {};
d.data?["data"]?.forEach((item) {
if (d_[item["roomName"]] == null) {
d_[item["roomName"]] = [];
}
d_[item["roomName"]].add(item);
});
List res_ = [];
d_.keys.forEach((key) {
res_.addAll(d_[key]);
});
model.deviceList = res_;
if (model.deviceMain != null && model.deviceMain["mac"] != null) {
bool isClose = false;
model.deviceList.forEach((item) {
if (item["mac"] == model.deviceMain["mac"]) {
model.deviceMain = item;
isClose = true;
updateAll();
}
});
if (!isClose) {
model.deviceMain = {};
updateAll();
showCustomConfirmAndCancelDialog(Get.context!, "设备已经被解绑,是否回到主界面?")
.then((e) {
if (e == "confirm") {
Get.find<MainPageController>().model.currentIndex = 0;
Get.offAllNamed("/mianPageBottomChange");
}
});
}
} else {
updateAll();
}
}).catchError((e) {
print("$e");
if (time > 0) {
getDeviceList(time: time - 1);
}
});
}
} }

View File

@@ -0,0 +1,33 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'person_controller.g.dart'; // 由json_serializable自动生成的部分
@JsonSerializable()
class PersonModel {
int read = 1;
DateTime? birthday;//是否不再提示教程 0 不再提示 1 需要提示
PersonModel();
// 从JSON反序列化时的异常处理
factory PersonModel.fromJson(Map<String, dynamic> json) {
try {
return _$PersonModelFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return PersonModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$PersonModelToJson(this);
}
class PersonController extends GetControllerEx<PersonModel> {
PersonController() {
attr = GetModel(PersonModel()).obs;
}
}

View File

@@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'person_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PersonModel _$PersonModelFromJson(Map<String, dynamic> json) => PersonModel()
..read = (json['read'] as num).toInt()
..birthday = json['birthday'] == null
? null
: DateTime.parse(json['birthday'] as String);
Map<String, dynamic> _$PersonModelToJson(PersonModel instance) =>
<String, dynamic>{
'read': instance.read,
'birthday': instance.birthday?.toIso8601String(),
};

View File

@@ -0,0 +1,33 @@
import 'dart:async';
import 'package:get/get.dart';
class CountdownController extends GetxController {
var countdown = 0.obs;
Timer? timer;
@override
void onInit() {
super.onInit();
}
void startCountdown(int seconds) {
timer?.cancel(); // 取消之前的定时器
countdown.value = seconds;
timer = Timer.periodic(Duration(seconds: 1), (timer) {
int elapsed = timer.tick;
int remaining = seconds - elapsed;
if (remaining > 0) {
countdown.value = remaining;
} else {
countdown.value = 0;
timer.cancel();
}
});
}
@override
void onClose() {
timer?.cancel();
super.onClose();
}
}

View File

@@ -1,19 +1,7 @@
import 'dart:io';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:get_storage/get_storage.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:path/path.dart' as p;
import 'package:uuid/uuid.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/model/user_data.dart'; import 'package:vbvs_app/model/user_data.dart';
part 'user_info_controller.g.dart'; part 'user_info_controller.g.dart';
@JsonSerializable() @JsonSerializable()
@@ -34,9 +22,13 @@ class UserInfoModel {
User? superbase_user; User? superbase_user;
String? img_bucket = 'user'; String? img_bucket = 'user';
int? login = 0; int? login = 1; //0未登录 1 登录
bool? register_agree = false; //注册协议
int? deviceBindNum = 0; //绑定设备数量
int? loginPhone = 0;//0 本机号码 1其他手机号
UserInfoModel(); UserInfoModel();
static UserInfoModel fromJson(Map<String, dynamic> json) => static UserInfoModel fromJson(Map<String, dynamic> json) =>

View File

@@ -19,8 +19,7 @@ UserInfoModel _$UserInfoModelFromJson(Map<String, dynamic> json) =>
..deviceModel = json['deviceModel'] as String? ..deviceModel = json['deviceModel'] as String?
..appVersion = json['appVersion'] as String? ..appVersion = json['appVersion'] as String?
..img_bucket = json['img_bucket'] as String? ..img_bucket = json['img_bucket'] as String?
..login = (json['login'] as num?)?.toInt() ..login = (json['login'] as num?)?.toInt();
..register_agree = json['register_agree'] as bool?;
Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) => Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) =>
<String, dynamic>{ <String, dynamic>{
@@ -34,5 +33,4 @@ Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) =>
'appVersion': instance.appVersion, 'appVersion': instance.appVersion,
'img_bucket': instance.img_bucket, 'img_bucket': instance.img_bucket,
'login': instance.login, 'login': instance.login,
'register_agree': instance.register_agree,
}; };

View File

@@ -4,9 +4,12 @@ import 'package:flutter/services.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/time/countdown_controller.dart';
import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/language/AppLanguage.dart';
import 'package:vbvs_app/model/CustomThemeColor.dart'; import 'package:vbvs_app/model/CustomThemeColor.dart';
import 'package:vbvs_app/model/user_data.dart'; import 'package:vbvs_app/model/user_data.dart';
@@ -25,6 +28,7 @@ Future<void> main() async {
// await GetStorage.init(); // await GetStorage.init();
// 初始化登录 // 初始化登录
await initLogin(); await initLogin();
await initLog();
// 检查网络 // 检查网络
// Checknetwork.checkNetwork(); // Checknetwork.checkNetwork();
// 微信开放平台注册 // 微信开放平台注册
@@ -41,6 +45,10 @@ Future<void> main() async {
// runApp(const MyApp()); // runApp(const MyApp());
} }
initLog() {
}
Future<void> initLogin() async { Future<void> initLogin() async {
// 初始化控制器 // 初始化控制器
Get.put(UserInfoController()); Get.put(UserInfoController());
@@ -155,6 +163,9 @@ class MyApp extends StatelessWidget {
Get.put(GlobalController()), Get.put(GlobalController()),
Get.lazyPut(() => MainPageController()), Get.lazyPut(() => MainPageController()),
Get.lazyPut(() => BlueteethBindController()), Get.lazyPut(() => BlueteethBindController()),
Get.lazyPut(() => PersonController()),
Get.lazyPut(() => CountdownController()),
Get.lazyPut(() => LoginController()),
])); ]));
}); });
} }

View File

@@ -0,0 +1,35 @@
class BleDeviceData {
final int type; // 协议版本
final int sn; // 广播包序号低8位
final String deviceId; // 设备唯一地址6字节
final int bre; // 呼吸
final int ht; // 心率
final int active; // 体动等级
final int flag; // 设备属性
final int version; // 软件版本
final int qsn; // 广播帧序列号高16位
int? status; // 设备状态
String? name;//设备名称
int? rssi;
String? mac;//mac地址
BleDeviceData({
required this.type,
required this.sn,
required this.deviceId,
required this.bre,
required this.ht,
required this.active,
required this.flag,
required this.version,
required this.qsn,
});
int get fullSeq => qsn * 256 + sn;
bool get isOnline => (flag & 0x01) != 0;
bool get sensorError => (flag & 0x02) != 0;
bool get apnea => (flag & 0x04) != 0;
bool get inBed => (flag & 0x08) != 0;
bool get expired => (flag & 0x10) != 0;
}

View File

@@ -0,0 +1,773 @@
import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
getOnePicker(context, List arr, int checkIndex, Function onSelectedItemChanged,
{bool looping = false}) {
return CupertinoPicker(
key: UniqueKey(),
useMagnifier: false,
itemExtent: 80.rpx,
magnification: 1,
diameterRatio: 3,
squeeze: 1,
looping: looping,
scrollController: FixedExtentScrollController(initialItem: checkIndex),
selectionOverlay: Container(),
onSelectedItemChanged: (int value) {
// print("$value");
onSelectedItemChanged.call(value);
},
children: [
...List.generate(arr.length, (index) {
return Container(
alignment: Alignment.center,
width: 400.rpx,
decoration: BoxDecoration(
border: Border(
bottom: index != arr.length
? BorderSide(
color: stringToColor("#8D95B0"),
)
: BorderSide.none,
),
),
child: Text("${arr[index]}",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx)),
);
})
],
);
}
Future showDateSelectionDialog(BuildContext context,
{required DateTime checkDate,
Function? checkChange,
String title = "选择生日"}) {
Color checkColor = stringToColor("#D3B684");
List years = [], months = [], days = [];
var days_select = [].obs;
int day_len = 31;
int year = DateTime.now().year;
for (var i = 0; i < 100; i++) {
years.insert(0, year - i);
}
for (var i = 1; i < 13; i++) {
months.add(i);
}
for (var i = 1; i < 32; i++) {
days.add(i);
}
int yearIndex = years.lastIndexOf(checkDate.year);
int monthIndex = months.lastIndexOf(checkDate.month);
day_len = DateTime.fromMillisecondsSinceEpoch(
DateTime(years[yearIndex], months[monthIndex] + 1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value = days.sublist(0, day_len);
int dayIndex = days.lastIndexOf(checkDate.day);
return showDialog(
// barrierColor: stringToColor("#000320"),
context: context,
barrierDismissible: true, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: stringToColor("#182B7C"),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: 60.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$title",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
closeIconWhite
],
),
),
Container(
height: 240.rpx,
margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Row(
children: [
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 40.rpx, right: 30.rpx),
child: getOnePicker(context, years, yearIndex,
(d) {
yearIndex = d;
dayIndex = 0;
day_len = DateTime.fromMillisecondsSinceEpoch(
DateTime(years[yearIndex],
months[monthIndex] + 1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value = days.sublist(0, day_len);
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 30.rpx),
child: getOnePicker(context, months, monthIndex,
(d) {
monthIndex = d;
dayIndex = 0;
day_len = DateTime.fromMillisecondsSinceEpoch(
DateTime(years[yearIndex],
months[monthIndex] + 1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value = days.sublist(0, day_len);
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 40.rpx),
child: Obx(
() {
// print("${dayIndex} ${day_len}");
return getOnePicker(
context,
days_select,
dayIndex,
(d) {
dayIndex = d;
},
);
},
),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
],
),
),
InkWell(
onTap: () {
checkChange?.call(DateTime(years[yearIndex],
months[monthIndex], days[dayIndex]));
Get.back();
},
child: Container(
height: 68.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
color: stringToColor("#D3B684"),
borderRadius: BorderRadius.circular(10.rpx),
),
child: Text(
"确定",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
)
],
),
),
),
),
),
],
);
},
);
}
Future showDayTimeSelectionDialog(BuildContext context,
{required List<int> dayTimeArr, Function? checkChange, String title = ""}) {
Color checkColor = stringToColor("#D3B684");
List hours = [], minutes = [];
for (var i = 0; i < 24; i++) {
hours.add(i);
}
for (var i = 0; i < 60; i++) {
minutes.add(i);
}
int hoursIndex = hours.lastIndexOf(dayTimeArr[0]);
int minutesIndex = minutes.lastIndexOf(dayTimeArr[1]);
return showDialog(
// barrierColor: stringToColor("#000320"),
context: context,
barrierDismissible: true, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: stringToColor("#182B7C"),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: 60.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$title",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
closeIconWhite
],
),
),
Container(
height: 240.rpx,
margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Row(
children: [
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 40.rpx, right: 30.rpx),
child: getOnePicker(context, hours, hoursIndex,
(d) {
hoursIndex = d;
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 30.rpx),
child: getOnePicker(
context, minutes, minutesIndex, (d) {
minutesIndex = d;
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
],
),
),
InkWell(
onTap: () {
checkChange?.call(
[hours[hoursIndex], minutes[minutesIndex]]);
Get.back();
},
child: Container(
height: 68.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
color: stringToColor("#D3B684"),
borderRadius: BorderRadius.circular(10.rpx),
),
child: Text(
"确定",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
)
],
),
),
),
),
),
],
);
},
);
}
Future showOneSelectionDialog(BuildContext context,
{required List arr,
int checkIndex = 0,
Function? checkChange,
String title = "选择性别"}) {
Color checkColor = stringToColor("#D3B684");
return showDialog(
// barrierColor: stringToColor("#000320"),
context: context,
barrierDismissible: true, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: stringToColor("#182B7C"),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: 60.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$title",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
closeIconWhite
],
),
),
Container(
height: 240.rpx,
alignment: Alignment.center,
margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Container(
width: 400.rpx,
child:
getOnePicker(context, arr, checkIndex, (index) {
checkIndex = index;
}),
)),
InkWell(
onTap: () {
checkChange?.call(checkIndex);
Get.back();
},
child: Container(
height: 68.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
color: stringToColor("#D3B684"),
borderRadius: BorderRadius.circular(10.rpx),
),
child: Text(
"确定",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
)
],
),
),
),
),
),
],
);
},
);
}
enum ConfirmDialogIcon {
none,
danger,
success,
warn;
get uname {
String v = "";
switch (this) {
case ConfirmDialogIcon.danger:
v = "danger";
break;
case ConfirmDialogIcon.success:
v = "success";
break;
case ConfirmDialogIcon.warn:
v = "warn";
break;
case ConfirmDialogIcon.none:
v = "";
break;
}
return v;
}
}
Future showCustomConfirmDialog(BuildContext context, String name,
{String btnName = "确定",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn}) async {
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
width: 660.rpx,
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: closeIcon,
),
SizedBox(height: 60.rpx),
if ("${icon.uname}".isNotEmpty)
Center(
child: Container(
margin: EdgeInsets.only(bottom: 39.rpx),
width: 50.rpx,
height: 50.rpx,
child: Image.asset("assets/images/toast/${icon.uname}.png"),
),
),
Center(
child: Text(
'${name}',
style: TextStyle(fontSize: 16),
),
),
SizedBox(height: 20.rpx),
Container(
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
alignment: Alignment.center,
child: InkWell(
onTap: () {
Get.back(result: "confirm");
},
child: Container(
width: 260.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: stringToColor("#D3B684")),
child: Text(
'$btnName',
style: TextStyle(color: Colors.white, fontSize: 30.rpx),
),
),
),
)
],
),
),
);
},
);
}
Future showCustomConfirmAndCancelDialog(BuildContext context, String name,
{String confirmName = "确定",
String cancelName = "取消",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn}) async {
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
width: 660.rpx,
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerRight,
child: closeIcon,
),
SizedBox(height: 40.rpx),
if ("${icon.uname}".isNotEmpty)
Center(
child: Container(
margin: EdgeInsets.only(bottom: 39.rpx),
width: 50.rpx,
height: 50.rpx,
child: Image.asset("assets/images/toast/${icon.uname}.png"),
),
),
Center(
child: Text(
'${name}',
style: TextStyle(fontSize: 16),
),
),
SizedBox(height: 20.rpx),
Container(
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
alignment: Alignment.center,
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
Get.back(result: "cancel");
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black12)),
child: Text(
'$cancelName',
style:
TextStyle(color: Colors.black, fontSize: 30.rpx),
),
),
),
SizedBox(
width: 80.rpx,
),
InkWell(
onTap: () {
Get.back(result: "confirm");
},
child: Container(
width: 200.rpx,
height: 60.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: stringToColor("#D3B684")),
child: Text(
'$confirmName',
style:
TextStyle(color: Colors.white, fontSize: 30.rpx),
),
),
)
],
)),
)
],
),
),
);
},
);
}
//权限说明弹窗
void showPermissionInfoDialog(BuildContext context, List data) {
showDialog(
context: context,
barrierDismissible: false, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
top: 30.rpx, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: Colors.white,
insetPadding: EdgeInsets.fromLTRB(0, 0, 0, 0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
constraints: BoxConstraints(maxHeight: 500.rpx),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
...List.generate(data.length, (index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${data[index][0]}",
style: TextStyle(
fontSize: 30.rpx,
color: stringToColor("#333333"),
),
),
SizedBox(
height: 4.rpx,
),
Text(
"${data[index][1]}",
style: TextStyle(
fontSize: 26.rpx,
color: stringToColor("#A4AABC"),
),
),
if (index != data.length - 1)
SizedBox(
height: 18.rpx,
),
],
);
}),
],
),
),
),
),
),
),
],
);
},
);
}

View File

@@ -0,0 +1,320 @@
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/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/user_info_controller.dart';
class BindDeviceSuccess extends StatefulWidget {
const BindDeviceSuccess({super.key});
@override
State<BindDeviceSuccess> createState() => _EPageState();
}
class _EPageState extends State<BindDeviceSuccess> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = 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: stringToColor("#242835"),
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
// color: Colors.grey,
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'绑定成功.标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(113.rpx, 0, 113.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 74.rpx, 0, 0),
child: Container(
width: 124.rpx,
height: 124.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tick.svg',
fit: BoxFit.cover,
color: Colors.white,
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 42.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',
fontSize: 48.rpx,
letterSpacing: 0.0,
color: Colors.white,
),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 265.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',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: Colors.white,
),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 48.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'绑定成功.分享内容'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: Colors.white,
),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 110.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
print('Button pressed ...');
Get.toNamed("/deviceType");
},
colors: [
// 渐变色
stringToColor("45D989"), // 左侧渐变色
stringToColor("00C1AA"), // 右侧渐变色
],
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: [
SvgPicture.asset(
'assets/img/icon/share.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: Colors.white, // 设置图标颜色为白色
),
Text(
'绑定成功.立即分享'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: Colors.white, // 文字颜色
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 18.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
Get.offAllNamed("/mianPageBottomChange");
},
colors: [
// 渐变色
stringToColor("45D989"), // 左侧渐变色
stringToColor("00C1AA"), // 右侧渐变色
],
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: Colors.white, // 文字颜色
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 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: [Colors.white.withOpacity(0.06)], // 背景色
colors: [stringToColor("#242835")], // 背景色
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,
),
),
],
),
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,294 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
class DoubleBlueteethDeviceCompoentWidget extends StatefulWidget {
const DoubleBlueteethDeviceCompoentWidget({super.key});
@override
State<DoubleBlueteethDeviceCompoentWidget> createState() =>
_DoubleBlueteethDeviceCompoentWidgetState();
}
class _DoubleBlueteethDeviceCompoentWidgetState
extends State<DoubleBlueteethDeviceCompoentWidget> {
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF242835),
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 36.rpx, 0, 52.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'AITH-V3',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'信号强度:-36dBm',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'SN12',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF5F9FD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 40.rpx)),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'蓝牙地址48:CA:43:B1:B3:B2',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'mac48CA43B1B3B0',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'网络:在线',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'传感器:',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'可绑定',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFF1AD2B5),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
],
),
].divide(SizedBox(width: 145.rpx)),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'版本02409.0301',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
Divider(
thickness: 2.rpx,
color: FlutterFlowTheme.of(context).alternate,
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'AITH-V3',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'信号强度:-36dBm',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'SN12',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF5F9FD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 40.rpx)),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'蓝牙地址48:CA:43:B1:B3:B2',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'mac48CA43B1B3B0',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'网络:在线',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'传感器:',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
'可绑定',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFF1AD2B5),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
],
),
].divide(SizedBox(width: 145.rpx)),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Text(
'版本02409.0301',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
),
].divide(SizedBox(height: 37.rpx)),
),
),
);
}
}

View File

@@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
class FancyCircleCheckbox extends StatefulWidget {
final bool value;
final ValueChanged<bool> onChanged;
final Color borderColor;
final Color fillColor;
const FancyCircleCheckbox({
Key? key,
required this.value,
required this.onChanged,
this.borderColor = Colors.white,
this.fillColor = Colors.blue,
}) : super(key: key);
@override
State<FancyCircleCheckbox> createState() => _FancyCircleCheckboxState();
}
class _FancyCircleCheckboxState extends State<FancyCircleCheckbox>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(milliseconds: 200),
vsync: this,
);
_scaleAnimation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
if (widget.value) {
_controller.forward();
}
}
@override
void didUpdateWidget(covariant FancyCircleCheckbox oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.value != oldWidget.value) {
widget.value ? _controller.forward() : _controller.reverse();
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => widget.onChanged(!widget.value),
child: Container(
width: 24,
height: 24,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: widget.value
? widget.borderColor
: widget.borderColor.withOpacity(0.5),
width: 1,
),
),
child: ScaleTransition(
scale: _scaleAnimation,
child: Container(
margin: EdgeInsets.all(5),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: widget.fillColor,
),
),
),
),
);
}
}

View File

@@ -0,0 +1,184 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutterflow_ui/flutterflow_ui.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';
import 'package:vbvs_app/model/BleDeviceData.dart';
import 'package:vbvs_app/pages/device_bind/blueteeth_device_page.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class SingleBlueteethDeviceCompoentWidget extends StatefulWidget {
// final BleDeviceData device;
final bleDevice;
const SingleBlueteethDeviceCompoentWidget({
super.key,
// required this.device,
required this.bleDevice,
});
@override
State<SingleBlueteethDeviceCompoentWidget> createState() =>
_SingleBlueteethDeviceCompoentWidgetState();
}
class _SingleBlueteethDeviceCompoentWidgetState
extends State<SingleBlueteethDeviceCompoentWidget> {
@override
Widget build(BuildContext context) {
var bleDevice = widget.bleDevice;
List<int> rawData =
widget.bleDevice.advertisementData.manufacturerData[0xFFED]!;
BleDeviceData deviceData = parseBleData(rawData);
deviceData.name = widget.bleDevice.advertisementData.advName;
deviceData.rssi = widget.bleDevice.rssi;
deviceData.mac = deviceData.deviceId.replaceAll(':', '');
BleDeviceData device = deviceData;
ThemeController themeController = Get.find();
return ClickableContainer(
backgroundColor: themeController.currentColor.sc5,
highlightColor: Colors.white,
borderRadius: 20.rpx,
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 36.rpx, 0, 52.rpx),
onTap: () async {
//todo 请求绑定
print(device.mac);
// try {
// await bleDevice.device.connect(autoConnect: false);
// List<BluetoothService> services =
// await bleDevice.device.discoverServices();
// BluetoothCharacteristic? wifiListChar;
// BluetoothCharacteristic? wifiSsidChar;
// BluetoothCharacteristic? wifiPasswordChar;
// BluetoothCharacteristic? startProvisionChar;
// for (BluetoothService service in services) {
// for (BluetoothCharacteristic c in service.characteristics) {
// if (c.uuid.toString() == 'YOUR_WIFI_LIST_UUID') {
// wifiListChar = c;
// } else if (c.uuid.toString() == 'YOUR_WIFI_SSID_UUID') {
// wifiSsidChar = c;
// } else if (c.uuid.toString() == 'YOUR_WIFI_PWD_UUID') {
// wifiPasswordChar = c;
// } else if (c.uuid.toString() == 'YOUR_WIFI_START_UUID') {
// startProvisionChar = c;
// }
// }
// }
// } catch (e) {
// print("蓝牙连接失败");
// }
//
// Get.toNamed('/wifiPage', arguments: bleDevice.device);
showBindDoubleDialog(context,[]);
// showHaveBindDialog(context);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Text(
device.name ?? '蓝牙绑定.默认设备名称'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFF6FAFD),
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
Row(
children: [
Text(
"蓝牙绑定.信号强度".tr + '${device.rssi ?? '-'}dBm',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
SizedBox(width: 40.rpx),
Text(
"蓝牙绑定.SN".tr + '${device.sn ?? '-'}',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFF5F9FD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
],
),
Text(
"蓝牙绑定.蓝牙地址".tr + '${device.deviceId ?? '-'}',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
"蓝牙绑定.mac".tr + '${device.mac ?? '-'}',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Row(
children: [
Text(
"蓝牙绑定.网络".tr +
'${device.isOnline == true ? '蓝牙绑定.在线'.tr : '蓝牙绑定.离线'.tr}',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
SizedBox(width: 145.rpx),
Row(
children: [
Text(
"蓝牙绑定.传感器".tr + "",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFEBF2F8),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Text(
device.status == 1 ? '蓝牙绑定.可绑定'.tr : '蓝牙绑定.已被绑定'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFF1AD2B5),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
],
),
],
),
Text(
'版本:${device.version ?? '-'}',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
color: const Color(0xFFF6FAFD),
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 37.rpx)),
),
);
}
}

View File

@@ -0,0 +1,324 @@
import 'dart:ui';
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/CustomCard.dart';
import 'package:vbvs_app/component/tool/FrostedDialog.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';
import 'package:vbvs_app/pages/device_bind/componnet/FancyCircleCheckbox.dart';
void showBindDoubleDialog(BuildContext context, List<BleDeviceData> devices) {
ThemeController themeController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
blueteethBindController.model.deviceIndex0 = true;
blueteethBindController.model.deviceIndex1 = false;
blueteethBindController.model.deviceIndex2 = false;
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(60.rpx, 0, 60.rpx, 0),
child: Container(
width: double.infinity,
constraints: BoxConstraints(
maxHeight: MediaQuery.sizeOf(context).height * 0.656,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 标题
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 93.rpx, 0, 0),
child: Text(
'蓝牙绑定.双人版绑定标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
),
// 全选
_buildCheckboxRow(
context,
title: '蓝牙绑定.绑定全部'.tr,
value: () => blueteethBindController.model.deviceIndex0!,
onChanged: (v) {
if (!blueteethBindController.model.deviceIndex0!) {
blueteethBindController.model.deviceIndex0 = v;
blueteethBindController.model.deviceIndex1 = !v;
blueteethBindController.model.deviceIndex2 = !v;
blueteethBindController.updateAll();
}
},
),
// 主设备
_buildCheckboxRow(
context,
title: '蓝牙绑定.主设备'.tr,
value: () => blueteethBindController.model.deviceIndex1!,
onChanged: (v) {
if (!blueteethBindController.model.deviceIndex1!) {
blueteethBindController.model.deviceIndex1 = v;
blueteethBindController.model.deviceIndex0 = !v;
blueteethBindController.model.deviceIndex2 = !v;
blueteethBindController.updateAll();
}
},
),
// 从设备
_buildCheckboxRow(
context,
title: '蓝牙绑定.从设备'.tr,
value: () => blueteethBindController.model.deviceIndex2!,
onChanged: (v) {
if (!blueteethBindController.model.deviceIndex2!) {
blueteethBindController.model.deviceIndex2 = v;
blueteethBindController.model.deviceIndex0 = !v;
blueteethBindController.model.deviceIndex1 = !v;
blueteethBindController.updateAll();
}
},
),
// 确定按钮
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 100.rpx, 0, 0),
child: _buildActionButton(
context,
text: '蓝牙绑定.确定'.tr,
onTap: () {
Get.back();
},
),
),
// 取消按钮
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 19.rpx, 0, 60.rpx),
child: _buildActionButton(
context,
text: '蓝牙绑定.取消'.tr,
onTap: () {
Get.back();
},
),
),
],
),
),
),
);
},
);
}
void showHaveBindDialog(BuildContext context) {
ThemeController themeController = 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(60.rpx, 0, 60.rpx, 0),
child: Container(
width: double.infinity,
constraints: BoxConstraints(
maxHeight: MediaQuery.sizeOf(context).height * 0.656,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 93.rpx, 0.rpx, 0.rpx),
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.rpx, 70.rpx, 0.rpx, 56.rpx),
child: RichText(
text: TextSpan(children: [
TextSpan(
text: "蓝牙绑定.无法绑定1".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
),
),
TextSpan(
text: "蓝牙绑定.无法绑定2".tr,
style: TextStyle(
color: themeController.currentColor.sc10,
fontSize: AppConstants().normal_text_fontSize,
),
),
TextSpan(
text: "蓝牙绑定.无法绑定3".tr,
style: TextStyle(
color: themeController.currentColor.sc3,
fontSize: AppConstants().normal_text_fontSize,
),
),
]),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 19.rpx, 0, 60.rpx),
child: CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
Get.back();
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: MediaQuery.sizeOf(context).width,
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: Colors.white,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
],
),
),
),
);
},
);
}
Widget _buildCheckboxRow(
BuildContext context, {
required String title,
required bool Function() value,
required void Function(bool) onChanged,
}) {
ThemeController themeController = Get.find();
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(60.rpx, 64.rpx, 0.rpx, 0.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Obx(() => FancyCircleCheckbox(
borderColor: themeController.currentColor.sc3,
fillColor: themeController.currentColor.sc2,
value: value(),
onChanged: onChanged,
)),
Text(
title,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
].divide(SizedBox(width: 21.rpx)),
),
);
}
Widget _buildActionButton(
BuildContext context, {
required String text,
required VoidCallback onTap,
}) {
ThemeController themeController = Get.find();
return CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: onTap,
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: MediaQuery.sizeOf(context).width,
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(
text,
style: FlutterFlowTheme.of(context).bodyMedium.override(
color: Colors.white,
fontFamily: 'Inter',
fontSize: AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
);
}

View File

@@ -1,12 +1,15 @@
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/FrostedDialog.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart'; import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
class DeviceTypePage extends StatefulWidget { class DeviceTypePage extends StatefulWidget {
@@ -20,6 +23,7 @@ class _EPageState extends State<DeviceTypePage> {
GlobalController globalController = Get.find(); GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find(); UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find(); BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
@override @override
void initState() { void initState() {
@@ -31,11 +35,7 @@ class _EPageState extends State<DeviceTypePage> {
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
return Dialog( return FrostedDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
backgroundColor: Colors.transparent,
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: Container( child: Container(
@@ -72,12 +72,22 @@ class _EPageState extends State<DeviceTypePage> {
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
Icon( Padding(
Icons.volume_mute, padding:
color: EdgeInsetsDirectional.fromSTEB(
FlutterFlowTheme.of(context) 0, 8.rpx, 0, 0),
.primaryText, child: Container(
size: 30.rpx, width: 25.rpx,
height: 25.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/sound.svg',
fit: BoxFit.fill,
color: themeController
.currentColor.sc8,
),
),
), ),
Expanded( Expanded(
child: Column( child: Column(
@@ -97,13 +107,12 @@ class _EPageState extends State<DeviceTypePage> {
letterSpacing: 0.0, letterSpacing: 0.0,
fontWeight: fontWeight:
FontWeight.w500, FontWeight.w500,
color: color: Colors.orange),
Colors.orange),
), ),
Text( Text(
'绑定引导.说明正文'.tr, '绑定引导.说明正文'.tr,
style: FlutterFlowTheme.of( style:
context) FlutterFlowTheme.of(context)
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
@@ -124,14 +133,13 @@ class _EPageState extends State<DeviceTypePage> {
), ),
Container( Container(
width: double.infinity, width: double.infinity,
height: (MediaQuery.sizeOf(context).width) * height:
0.13, (MediaQuery.sizeOf(context).width) * 0.13,
constraints: BoxConstraints( constraints: BoxConstraints(
minHeight: 200.rpx, minHeight: 200.rpx,
), ),
child: ClipRRect( child: ClipRRect(
borderRadius: borderRadius: BorderRadius.circular(20.rpx),
BorderRadius.circular(20.rpx),
// child: Image.network( // child: Image.network(
// 'https://picsum.photos/seed/861/600', // 'https://picsum.photos/seed/861/600',
// fit: BoxFit.cover, // fit: BoxFit.cover,
@@ -149,8 +157,8 @@ class _EPageState extends State<DeviceTypePage> {
), ),
Flexible( Flexible(
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding:
0, 210.rpx, 0, 0), EdgeInsetsDirectional.fromSTEB(0, 210.rpx, 0, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
child: Column( child: Column(
@@ -160,8 +168,7 @@ class _EPageState extends State<DeviceTypePage> {
width: double.infinity, width: double.infinity,
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: mainAxisAlignment: MainAxisAlignment.center,
MainAxisAlignment.center,
children: [ children: [
Theme( Theme(
data: ThemeData( data: ThemeData(
@@ -181,14 +188,16 @@ class _EPageState extends State<DeviceTypePage> {
), ),
child: Obx( child: Obx(
() => Checkbox( () => Checkbox(
value: userInfoController value: blueteethBindController
.model.register_agree ?? .model.read ==
false, 1
? false
: true,
onChanged: (newValue) async { onChanged: (newValue) async {
userInfoController.model blueteethBindController
.register_agree = .model.read =
newValue; newValue == true ? 0 : 1;
userInfoController blueteethBindController
.updateAll(); .updateAll();
// 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取 // 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取
// if (newValue == true) { // if (newValue == true) {
@@ -198,8 +207,8 @@ class _EPageState extends State<DeviceTypePage> {
}, },
side: BorderSide( side: BorderSide(
width: 1.5, width: 1.5,
color: FlutterFlowTheme.of( color:
context) FlutterFlowTheme.of(context)
.secondaryText, .secondaryText,
), ),
activeColor: activeColor:
@@ -234,13 +243,12 @@ class _EPageState extends State<DeviceTypePage> {
stringToColor("45D989"), stringToColor("45D989"),
stringToColor("00C1AA") stringToColor("00C1AA")
], // 单色背景也用渐变写法 ], // 单色背景也用渐变写法
title: '',
child: Container( child: Container(
width: MediaQuery.sizeOf(context).width * width:
0.66, MediaQuery.sizeOf(context).width * 0.66,
height: height:
MediaQuery.sizeOf(context).height * MediaQuery.sizeOf(context).height * 0.055,
0.055,
constraints: BoxConstraints( constraints: BoxConstraints(
minWidth: 500.rpx, minWidth: 500.rpx,
minHeight: 90.rpx, minHeight: 90.rpx,
@@ -275,7 +283,7 @@ class _EPageState extends State<DeviceTypePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
int read = blueteethBindController.model.read; int read = blueteethBindController.model.read!;
if (blueteethBindController.model.read == 1) { if (blueteethBindController.model.read == 1) {
//需要弹窗显示教程 //需要弹窗显示教程
} }
@@ -378,11 +386,12 @@ class _EPageState extends State<DeviceTypePage> {
if (type == '1') { if (type == '1') {
Get.toNamed("/blueteethDevice"); Get.toNamed("/blueteethDevice");
} }
if (type == '2') {
Get.toNamed("/wifiPage");
}
} }
}, },
// colors: [Colors.white.withOpacity(0.06)], // 背景色
colors: [stringToColor("#242835")], // 背景色 colors: [stringToColor("#242835")], // 背景色
title: title,
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.135, height: MediaQuery.sizeOf(context).height * 0.135,

View File

@@ -0,0 +1,502 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/Ble.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/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/common/util/Ble.dart' as ble;
import 'package:vbvs_app/pages/common/selectDialog.dart';
class WifiPage extends StatefulWidget {
// ble.ConnectedDeviceProp connectedDeviceProp;
BluetoothDevice bluetoothDevice;
// WifiPage({super.key, required this.connectedDeviceProp});
WifiPage({super.key, required this.bluetoothDevice});
@override
State<WifiPage> createState() => _WifiPageState();
}
class _WifiPageState extends State<WifiPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = Get.find();
ThemeController themeController = Get.find();
late ble.ConnectedDeviceProp connectedDeviceProp;
@override
void initState() {
super.initState();
connectToDevice(widget.bluetoothDevice);
// connectedDeviceProp = widget.connectedDeviceProp;
Timer(const Duration(microseconds: 100), () {
getWifiList();
});
}
@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: stringToColor("#242835"),
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
// color: Colors.grey,
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'wifi页.标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
Get.offAllNamed("/bindDeviceSuccess");
},
colors: [
stringToColor("#45D989"),
stringToColor("#00C1AA"),
],
child: Container(
width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 0, 16.rpx, 0),
child: Text(
'wifi页.跳过'.tr,
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Inter Tight',
color: Colors.white,
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(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,
),
),
],
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 25.rpx, 0.rpx, 0.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(20.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'可用WLAN',
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)),
),
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(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3),
),
].divide(SizedBox(width: 26.rpx)),
),
].divide(SizedBox(height: 65.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: [Colors.white.withOpacity(0.06)], // 背景色
colors: [stringToColor("#242835")], // 背景色
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,
),
),
],
),
),
);
}
getWifiList({int time = 3}) {
// LoadingDialog.show("扫描WIFI列表中...", icon: LoadingDialogIcon.wifi);
try {
var device = widget.bluetoothDevice;
String log = "";
Function logAdd = (l) {
log += l;
};
connectedDeviceProp.receiveLogArr.add(logAdd);
connectedDeviceProp.write3OfString("wscan scan", success: () {
Timer.periodic(const Duration(milliseconds: 1000), (timer) async {
if (timer.tick > 8) {
timer.cancel();
connectedDeviceProp.receiveLogArr.remove(logAdd);
LoadingDialog.hide();
if (time > 0) {
getWifiList(time: time - 1);
}
}
Iterable<RegExpMatch> a = RegExp(
r'ITEM:SSID=([^\t]*)\s*RSSI=(\S*)\s*(,\s*auth\s*=\s*(\S*))?')
.allMatches(log);
if (a.isEmpty == false) {
await Future.delayed(const Duration(milliseconds: 500));
a = RegExp(
r'ITEM:SSID=([^\t]*)\s*RSSI=(\S*)\s*(,\s*auth\s*=\s*(\S*))?')
.allMatches(log);
List arr = [];
for (RegExpMatch one in a) {
arr.add({"name": one[1], "num": one[2], "auth": one[4]});
}
LoadingDialog.hide();
blueteethBindController.model.wifiList = arr;
blueteethBindController.updateAll();
connectedDeviceProp.receiveLogArr.remove(logAdd);
timer.cancel();
checkIsCalibration();
}
});
}, fail: () {
connectedDeviceProp.receiveLogArr.remove(logAdd);
LoadingDialog.hide();
});
} catch (e) {
print(e);
}
}
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();
// }
});
}
}

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/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/login/login_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
@@ -20,6 +21,7 @@ class LoginPage extends StatefulWidget {
class _EPageState extends State<LoginPage> { class _EPageState extends State<LoginPage> {
GlobalController globalController = Get.find(); GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find(); UserInfoController userInfoController = Get.find();
LoginController loginController = Get.find();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -75,36 +77,6 @@ class _EPageState extends State<LoginPage> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
// ClickableContainer(
// backgroundColor: Colors.transparent, // 容器背景色为透明
// highlightColor: Colors.pink, // 点击时背景色也为透明
// padding: EdgeInsets.all(0), // 没有额外的内边距
// onTap: () {
// // 你可以在这里定义点击事件的回调,比如关闭页面等
// print('关闭按钮被点击');
// },
// borderRadius: 0, // 没有圆角
// child: Container(
// // color: Colors.red,
// // width: double.infinity, // 使容器宽度充满父容器
// child: Align(
// alignment:
// AlignmentDirectional(-1, 0), // 左对齐
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 66.rpx, 0, 0),
// child: SvgPicture.asset(
// 'assets/img/icon/close.svg',
// width: 25.rpx,
// height: 25
// .rpx, // 如果 SVG 中没有固定颜色,使用 color 设置
// color: Colors.white, // 这里设置了颜色
// ),
// ),
// ),
// ),
// ),
Align( Align(
alignment: AlignmentDirectional(-1, 0), alignment: AlignmentDirectional(-1, 0),
child: Padding( child: Padding(
@@ -190,16 +162,20 @@ class _EPageState extends State<LoginPage> {
borderRadius: AppConstants() borderRadius: AppConstants()
.button_container_radius, // 圆角半径 .button_container_radius, // 圆角半径
onTap: () { onTap: () {
print('Button pressed ...'); bool agree = loginController
// Get.toNamed("/deviceType"); .model.register_agree!;
if (!agree) {
print('未授权 ...');
} else {
print('已授权 ...');
}
}, },
colors: [ colors: [
//todo 颜色 //todo 颜色
stringToColor("45D989"), stringToColor("45D989"),
stringToColor("00C1AA") stringToColor("00C1AA")
], // 渐变色是同一个色,也可以根据需要调整 ], // 渐变色是同一个色,也可以根据需要调整
title:
'首页.蓝牙绑定'.tr, // 可选,虽然这个 title 没用,但可以作为调试用
child: Container( child: Container(
width: width:
// MediaQuery.sizeOf(context).width * 0.66, // MediaQuery.sizeOf(context).width * 0.66,
@@ -215,13 +191,6 @@ class _EPageState extends State<LoginPage> {
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
// Icon(
// Icons.arrow_back,
// color: FlutterFlowTheme.of(context)
// .primaryText,
// size: 28.rpx,
// ),
Text( Text(
'登录页.本机号码一键登录/注册'.tr, '登录页.本机号码一键登录/注册'.tr,
style: FlutterFlowTheme.of(context) style: FlutterFlowTheme.of(context)
@@ -242,39 +211,6 @@ class _EPageState extends State<LoginPage> {
), ),
), ),
), ),
// ClickableContainer(
// backgroundColor: Colors.transparent, // 背景色(透明)
// highlightColor: stringToColor(
// "#FF6347"), // 点击时的背景色,可以根据需求设置颜色
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 32.rpx, 0, 32.rpx), // 内部间距
// onTap: () {
// print('点击了“其他手机号码”'); // 点击后的回调事件
// // 这里可以放置点击后的逻辑,比如导航等
// },
// borderRadius: 0.rpx, // 可选的圆角参数,默认是 20.rpx
// child: Align(
// alignment: AlignmentDirectional(-1, 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',
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// color: stringToColor("#FFFFFF"),
// ),
// ),
// ),
// ),
// ),
// ),
SizedBox( SizedBox(
height: 20.rpx, height: 20.rpx,
), ),
@@ -285,6 +221,7 @@ class _EPageState extends State<LoginPage> {
16.rpx, 10.rpx, 16.rpx, 10.rpx), 16.rpx, 10.rpx, 16.rpx, 10.rpx),
onTap: () { onTap: () {
print('点击了容器'); print('点击了容器');
Get.toNamed("/otherLoginPage");
}, },
child: Text( child: Text(
'登录页.其他手机号码'.tr, // 子组件内容 '登录页.其他手机号码'.tr, // 子组件内容
@@ -306,14 +243,6 @@ class _EPageState extends State<LoginPage> {
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
// SvgPicture.asset(
// 'assets/img/icon/tick.svg',
// width: 30.rpx,
// height: 30.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// //todo 颜色
// // color: Colors.white,
// color: Colors.white,
// ),
Theme( Theme(
data: ThemeData( data: ThemeData(
checkboxTheme: CheckboxThemeData( checkboxTheme: CheckboxThemeData(
@@ -332,13 +261,13 @@ class _EPageState extends State<LoginPage> {
), ),
child: Obx( child: Obx(
() => Checkbox( () => Checkbox(
value: userInfoController value: loginController
.model.register_agree ?? .model.register_agree ??
false, false,
onChanged: (newValue) async { onChanged: (newValue) async {
userInfoController.model loginController.model
.register_agree = newValue; .register_agree = newValue;
userInfoController.updateAll(); loginController.updateAll();
// 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取 // 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取
// if (newValue == true) { // if (newValue == true) {
// Deviceconfig // Deviceconfig
@@ -358,7 +287,6 @@ class _EPageState extends State<LoginPage> {
.info, .info,
), ),
)), )),
Expanded( Expanded(
child: Padding( child: Padding(
padding: padding:

View File

@@ -0,0 +1,801 @@
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/login/login_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/time/countdown_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
class OtherLoginPage extends StatefulWidget {
const OtherLoginPage({super.key});
@override
State<OtherLoginPage> createState() => _OtherLoginPageState();
}
class _OtherLoginPageState extends State<OtherLoginPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
ThemeController themeController = Get.find();
CountdownController countdownController = Get.find();
LoginController loginController = Get.find();
@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/bgImage.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(75.rpx, 0.rpx, 75.rpx, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
SizedBox(
height: 66.rpx,
),
ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: Colors.green, // 点击时的背景色
padding:
EdgeInsets.zero, // 这里去掉外部的 padding避免影响点击范围
onTap: () {
Get.back();
},
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
16.rpx, 10.rpx, 16.rpx, 10.rpx),
child: SvgPicture.asset(
'assets/img/icon/arrow_left.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,使用 color 设置
color: Colors.white, // 这里设置了颜色
),
),
),
],
),
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 141.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'登录页.欢迎使用太和e护'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 48.rpx,
letterSpacing: 0.0,
//todo 颜色
color: stringToColor("#FFFFFF"),
),
),
),
),
),
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 15.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',
fontSize: 30.rpx,
letterSpacing: 0.0,
//todo 颜色
color: stringToColor("#FFFFFF"),
),
),
),
),
),
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 95.rpx, 0, 0),
child: Container(
width: double.infinity,
height: bodysize.maxHeight * 0.056,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConstants()
.button_container_radius),
border: Border.all(
color: Colors.white,
width: 1.rpx,
),
),
constraints: BoxConstraints(
minHeight: 90.rpx,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
35.rpx, 0, 35.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: TextFormField(
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,
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,
// validator: _model
// .textControllerValidator
// .asValidator(context),
),
),
),
),
],
),
),
),
),
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 19.rpx, 0, 0),
child: Container(
height: bodysize.maxHeight * 0.056,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConstants()
.button_container_radius),
border: Border.all(
color: Colors.white,
width: 1.rpx,
),
),
constraints: BoxConstraints(
minHeight: 90.rpx,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
35.rpx, 0, 35.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: TextFormField(
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: true,
fillColor:
Colors.transparent,
),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
cursorColor:
FlutterFlowTheme.of(
context)
.primaryText,
// validator: _model
// .textControllerValidator
// .asValidator(context),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
26.rpx, 0, 0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
height: 50.rpx,
child: VerticalDivider(
thickness: 2.rpx,
color: themeController
.currentColor.sc7,
),
),
// Text(
// countdownController.countdown
// .value ==
// 0
// ? '其他手机登录页.获取验证码'.tr
// : '${countdownController.countdown.value}秒',
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: themeController
// .currentColor.sc7,
// fontSize: AppConstants()
// .title_text_fontSize,
// letterSpacing: 0,
// ),
// ),
Obx(() {
final CountdownController
countdownController =
Get.find<
CountdownController>();
return InkWell(
onTap: () async {
if (countdownController
.countdown
.value !=
0) {
return;
}
String msg =
await loginController
.getCode(context);
if (msg.isNotEmpty) {
return;
}
countdownController
.countdown
.value ==
0
? countdownController
.startCountdown(
AppConstants
.code_time)
: null;
},
child: Container(
alignment:
Alignment.center,
constraints:
BoxConstraints(
minWidth: 150.rpx,
),
child: Text(
countdownController
.countdown
.value ==
0
? '获取验证码'
: '${countdownController.countdown.value}',
style: TextStyle(
fontFamily:
'Readex Pro',
color:
Color(0xFF333333),
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0,
),
),
),
);
}),
].divide(SizedBox(width: 26.rpx)),
),
),
],
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 35.rpx, 0, 0),
child: CustomCard(
borderRadius: AppConstants()
.button_container_radius, // 圆角半径
onTap: () {
bool agree =
loginController.model.register_agree!;
if (!agree) {
print('未授权 ...');
} else {
print('已授权 ...');
}
},
colors: [
//todo 颜色
stringToColor("45D989"),
stringToColor("00C1AA")
], // 渐变色是同一个色,也可以根据需要调整
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(
//todo 颜色
color: Colors.white,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
25.rpx, 83.rpx, 25.rpx, 50.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Theme(
data: ThemeData(
checkboxTheme: CheckboxThemeData(
visualDensity:
VisualDensity.compact,
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(64),
),
),
unselectedWidgetColor:
Color(0xFFD3D3D3),
),
child: Obx(
() => Checkbox(
value: loginController
.model.register_agree ??
false,
onChanged: (newValue) async {
loginController.model
.register_agree = newValue;
loginController.updateAll();
// 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取
// if (newValue == true) {
// Deviceconfig
// .initPlatformState();
// }
},
side: BorderSide(
width: 1.5,
color:
FlutterFlowTheme.of(context)
.secondaryText,
),
activeColor:
stringToColor("#FF9F66"),
checkColor:
FlutterFlowTheme.of(context)
.info,
),
)),
Expanded(
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
0.rpx, 10.rpx, 0.rpx, 0.rpx),
child: Container(
width: bodysize.maxWidth,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: '登录页.协议1'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: Colors
.white, // 可以调整为你想要的颜色
),
),
TextSpan(
text: '登录页.协议2'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: stringToColor(
"#FF9F66"),
),
),
TextSpan(
text: '登录页.协议3'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: Colors
.white, // 可以调整为你想要的颜色
),
),
TextSpan(
text: '登录页.协议4'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: stringToColor(
"#FF9F66"),
),
),
TextSpan(
text: '登录页.协议5'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: Colors
.white, // 可以调整为你想要的颜色
),
),
TextSpan(
text: '登录页.协议6'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
fontSize: 26.rpx,
color: stringToColor(
"#FF9F66"),
),
),
],
),
),
),
),
),
].divide(SizedBox(width: 18.rpx)),
),
),
),
],
),
),
),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.136,
constraints: BoxConstraints(
minHeight: 220.rpx,
),
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 36.rpx),
child: Text(
'登录页.其他登录方式'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
//todo 颜色
color: stringToColor("#FFFFFF"),
),
),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 91.rpx,
height: 91.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/wechat.png",
width: 30.rpx,
height: 30.rpx,
),
),
Container(
width: 91.rpx,
height: 91.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/tel.png",
width: 30.rpx,
height: 30.rpx,
),
),
Container(
width: 91.rpx,
height: 91.rpx,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/img/google.png",
width: 30.rpx,
height: 30.rpx,
),
),
].divide(SizedBox(width: 35.rpx)),
),
],
),
),
],
),
),
),
),
)),
);
}
}

View File

@@ -5,6 +5,8 @@ import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/home_page/SleepDataModuleWidget.dart';
import 'package:vbvs_app/component/home_page/SleepDateWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
@@ -53,6 +55,7 @@ class _HomePageState extends State<HomePage> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Padding( Padding(
//用户信息
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
AppConstants().content_left_right_padding, AppConstants().content_left_right_padding,
0, 0,
@@ -64,13 +67,15 @@ class _HomePageState extends State<HomePage> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
CustomCard( Obx(() {
return Visibility(
visible:
userInfoController.model.login == 0,
child: CustomCard(
borderRadius: 20.rpx, borderRadius: 20.rpx,
onTap: () async { onTap: () async {
Get.toNamed("/loginPage"); Get.toNamed("/loginPage");
}, },
title: '首页.登录'
.tr, // 虽然 title 传入了,但当前组件里没用它(可忽略或用于调试)
colors: [ colors: [
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2, themeController.currentColor.sc2,
@@ -94,6 +99,28 @@ class _HomePageState extends State<HomePage> {
), ),
), ),
), ),
);
}),
Obx(() {
return Visibility(
visible:
userInfoController.model.login == 1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"飞行的鱼",
style: TextStyle(color: Colors.white),
),
Text(
"嘉兴 晴",
style: TextStyle(color: Colors.white),
),
],
),
);
}),
SvgPicture.asset( SvgPicture.asset(
'assets/img/icon/add.svg', 'assets/img/icon/add.svg',
width: 39.rpx, width: 39.rpx,
@@ -106,6 +133,7 @@ class _HomePageState extends State<HomePage> {
), ),
), ),
Padding( Padding(
//绑定数量
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
19.rpx, 34.rpx, 0, 21.rpx), 19.rpx, 34.rpx, 0, 21.rpx),
child: ClickableContainer( child: ClickableContainer(
@@ -116,7 +144,10 @@ class _HomePageState extends State<HomePage> {
}, },
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 10.rpx, 0, 10.rpx), 0.rpx, 10.rpx, 0, 10.rpx),
child: Container( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -126,11 +157,12 @@ class _HomePageState extends State<HomePage> {
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: fontSize: AppConstants()
AppConstants().title_text_fontSize, .title_text_fontSize,
letterSpacing: 0.0, letterSpacing: 0.0,
//todo 颜色 //todo 颜色
color: themeController.currentColor.sc3, color: themeController
.currentColor.sc3,
), ),
), ),
Text( Text(
@@ -139,19 +171,40 @@ class _HomePageState extends State<HomePage> {
.bodyMedium .bodyMedium
.override( .override(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: fontSize: AppConstants()
AppConstants().title_text_fontSize, .title_text_fontSize,
letterSpacing: 0.0, letterSpacing: 0.0,
color: themeController.currentColor.sc8, color: themeController
.currentColor.sc8,
), ),
), ),
].divide(SizedBox( ].divide(SizedBox(
width: 6.rpx, width: 6.rpx,
)), )),
)), )),
Obx(() {
return Visibility(
visible: userInfoController
.model.deviceBindNum! >
0,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 8.rpx, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 14.rpx,
height: 14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: Colors.white,
),
),
);
}),
],
),
), ),
), ),
Container( Container(
//未绑定布局
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.277, height: MediaQuery.sizeOf(context).height * 0.277,
constraints: BoxConstraints( constraints: BoxConstraints(
@@ -178,8 +231,7 @@ class _HomePageState extends State<HomePage> {
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2, themeController.currentColor.sc2,
], ],
title:
'首页.蓝牙绑定'.tr, // 可选,虽然这个 title 没用,但可以作为调试用
child: Container( child: Container(
width: width:
MediaQuery.sizeOf(context).width * 0.66, MediaQuery.sizeOf(context).width * 0.66,
@@ -229,8 +281,7 @@ class _HomePageState extends State<HomePage> {
themeController.currentColor.sc1, themeController.currentColor.sc1,
themeController.currentColor.sc2, themeController.currentColor.sc2,
], // 渐变色是同一个色,也可以根据需要调整 ], // 渐变色是同一个色,也可以根据需要调整
title:
'首页.蓝牙绑定'.tr, // 可选,虽然这个 title 没用,但可以作为调试用
child: Container( child: Container(
width: width:
MediaQuery.sizeOf(context).width * 0.66, MediaQuery.sizeOf(context).width * 0.66,
@@ -278,6 +329,7 @@ class _HomePageState extends State<HomePage> {
), ),
), ),
Padding( Padding(
//未绑定标语
padding: padding:
EdgeInsetsDirectional.fromSTEB(0, 26.rpx, 0, 0), EdgeInsetsDirectional.fromSTEB(0, 26.rpx, 0, 0),
child: Container( child: Container(
@@ -374,6 +426,213 @@ class _HomePageState extends State<HomePage> {
), ),
), ),
), ),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 26.rpx, 0, 0),
child: Container(
// color: Colors.red,
width: bodySize.maxWidth,
height: bodySize.maxHeight * 0.107,
constraints: BoxConstraints(
minHeight: 240.rpx,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor:
themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc3,
borderRadius:
AppConstants().normal_container_radius,
padding:
EdgeInsets.zero, // 原始Container没有padding
onTap: () {
// 点击逻辑放这里
},
child: Container(
width: bodySize.maxWidth * 0.445,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SizedBox(height: 32.rpx),
Container(
width: 120.rpx,
height: 120.rpx,
child: Image.asset(
"assets/img/netlove.png",
fit: BoxFit.cover,
),
),
Text(
"首页.我的e护".tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
),
),
SizedBox(height: 32.rpx),
],
),
),
),
ClickableContainer(
backgroundColor:
themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc3,
borderRadius:
AppConstants().normal_container_radius,
padding: EdgeInsets
.zero, // 原本的Container没有 padding这里设置为 zero
onTap: () {
// TODO: 替换为你需要的点击事件逻辑
print("云关爱 被点击");
},
child: SizedBox(
width: bodySize.maxWidth * 0.445,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Container(
width: 120.rpx,
height: 120.rpx,
child: Image.asset(
"assets/img/mye.png",
fit: BoxFit.cover,
),
),
Text(
"首页.云关爱".tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
),
),
]
.addToStart(SizedBox(height: 32.rpx))
.addToEnd(SizedBox(height: 32.rpx)),
),
),
),
],
),
),
),
// Generated code for this Container Widget...
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 25.rpx, 0, 25.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: double.infinity,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'次卧/1201/李小北',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'首页.报告详情'.tr,
style:
FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
Padding(
padding: EdgeInsetsDirectional
.fromSTEB(0, 6.rpx, 0, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 14.rpx,
height: 14
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: Colors.white,
),
),
].divide(SizedBox(width: 22.rpx)),
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
SleepDateWidget(),
SleepDateWidget(),
SleepDateWidget(),
SleepDateWidget(),
SleepDateWidget(),
SleepDateWidget(),
].divide(SizedBox(
width: 20.rpx,
)),
),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
SleepDataModuleWidget(),
SleepDataModuleWidget(),
SleepDataModuleWidget(),
SleepDataModuleWidget(),
SleepDataModuleWidget(),
].divide(SizedBox(
width: 14.rpx)), // ✅ 这里加了 .rpx
),
),
),
],
),
),
),
)
], ],
), ),
), ),

View File

@@ -90,7 +90,14 @@ class MainPageBottomChange extends GetView<MainPageController> {
floatingActionButton: Container(), floatingActionButton: Container(),
); );
} else { } else {
return Scaffold( return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgImage.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
body: arr[controller.model.currentIndex], body: arr[controller.model.currentIndex],
floatingActionButtonAnimator: floatingActionButtonAnimator:
@@ -112,7 +119,8 @@ class MainPageBottomChange extends GetView<MainPageController> {
onTap: (index) { onTap: (index) {
Future.delayed(const Duration(milliseconds: 500), () { Future.delayed(const Duration(milliseconds: 500), () {
if (controller.model.currentIndex != 1) { if (controller.model.currentIndex != 1) {
globalController.model.hideBottomNavigationBar = false; globalController.model.hideBottomNavigationBar =
false;
globalController.updateAll(); globalController.updateAll();
} }
}); });
@@ -133,6 +141,7 @@ class MainPageBottomChange extends GetView<MainPageController> {
], ],
), ),
), ),
),
); );
} }
}, },

View File

@@ -0,0 +1,619 @@
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/common/util/MyUtils.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/person/person_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/person/select_time.dart';
class PersonPage extends StatefulWidget {
const PersonPage({super.key});
@override
State<PersonPage> createState() => _EPageState();
}
class _EPageState extends State<PersonPage> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
PersonController personController = 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: stringToColor("#242835"),
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
// color: Colors.grey,
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'人员资料.标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtom,
),
Positioned(
right: 20.rpx,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
Get.offAllNamed("/bindDeviceSuccess");
},
colors: [
stringToColor("#45D989"),
stringToColor("#00C1AA"),
],
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: Colors.white,
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,
autofocus: false,
obscureText: false,
decoration: InputDecoration(
fillColor: Colors.transparent,
isDense: true,
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: Colors.white),
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: Colors.white),
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: Image.asset(
"assets/img/man.png",
fit: BoxFit.cover,
),
),
),
Text(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
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(
'',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
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(
// 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: Obx(
// () => Container(
// width: double.infinity,
// height:
// MediaQuery.sizeOf(context).height * 0.064,
// decoration: BoxDecoration(),
// child: InkWell(
// onTap: () {
// // 触摸收起键盘
// FocusScope.of(context)
// .requestFocus(FocusNode());
// Future.delayed(
// const Duration(milliseconds: 250), () {
// // 延迟执行的代码
// showDateSelectionDialog(context,
// checkDate:
// personController.model.birthday ??
// DateTime.now(),
// checkChange: (DateTime d) {
// personController.model.birthday = d;
// personController.updateAll();
// print("$d");
// }).then((d) {
// // Timer(Duration.zero, () {
// // FocusScope.of(context).unfocus();
// // });
// });
// });
// },
// child: Container(
// constraints:
// BoxConstraints(minWidth: 200.rpx),
// child: Text(
// personController.model.birthday != null
// ? DateFormat("yyyy年MM月dd日").format(
// personController.model.birthday!)
// : '人员资料.生日输入提示'.tr,
// textAlign: TextAlign.right,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// fontSize: 30.rpx,
// letterSpacing: 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.model.birthday ??
DateTime.now(),
checkChange: (DateTime d) {
personController.model.birthday = d;
personController.updateAll();
},
);
});
},
child: Center(
child: Text(
personController.model.birthday != null
? DateFormat("yyyy年MM月dd日").format(
personController.model.birthday!)
: '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: personController.model.birthday !=
null
? Colors.white
: Colors.grey,
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: 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,
),
hintText: '人员资料.体重输入提示'.tr,
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Inter',
color: personController.model.birthday !=
null
? Colors.white
: Colors.grey,
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,
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
letterSpacing: 0.0,
color: Colors.white,
),
textAlign: TextAlign.center,
cursorColor:
FlutterFlowTheme.of(context).primaryText,
// validator: _model.textController3Validator
// .asValidator(context),
),
),
),
),
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,
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 70.rpx, 70.rpx, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
),
),
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: [Colors.white.withOpacity(0.06)], // 背景色
colors: [stringToColor("#242835")], // 背景色
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,290 @@
import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/theme_controller/ThemeController.dart';
Future showDateSelectionDialog(BuildContext context,
{required DateTime checkDate, Function? checkChange, String title = "生日"}) {
Color checkColor = stringToColor("#D3B684");
List years = [], months = [], days = [];
var days_select = [].obs;
int day_len = 31;
int year = DateTime.now().year;
for (var i = 0; i < 100; i++) {
years.insert(0, year - i);
}
for (var i = 1; i < 13; i++) {
months.add(i);
}
for (var i = 1; i < 32; i++) {
days.add(i);
}
int yearIndex = years.lastIndexOf(checkDate.year);
int monthIndex = months.lastIndexOf(checkDate.month);
day_len = DateTime.fromMillisecondsSinceEpoch(
DateTime(years[yearIndex], months[monthIndex] + 1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value = days.sublist(0, day_len);
int dayIndex = days.lastIndexOf(checkDate.day);
ThemeController themeController = Get.find();
return showDialog(
// barrierColor: stringToColor("#000320"),
context: context,
barrierDismissible: true, // 点击对话框外部可关闭
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0, // 控制弹窗距离顶部的位置
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: stringToColor("#242835"),
// backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
AppConstants().normal_container_radius),
topRight: Radius.circular(
AppConstants().normal_container_radius),
bottomLeft: Radius.circular(0.rpx),
bottomRight: Radius.circular(0.rpx),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
color: themeController.currentColor.sc5,
alignment: Alignment.centerLeft,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
InkWell(
child: Text(
"日期.取消".tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: AppConstants()
.normal_text_fontSize),
),
onTap: () {
Get.back();
},
),
Text(
"$title",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize:
AppConstants().title_text_fontSize),
),
// closeIconWhite,
InkWell(
child: Text(
"日期.确定".tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: AppConstants()
.normal_text_fontSize),
),
onTap: () {
checkChange?.call(DateTime(years[yearIndex],
months[monthIndex], days[dayIndex]));
Get.back();
},
)
],
),
),
Container(
height: 240.rpx,
margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx),
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Container(
child: Row(
children: [
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 40.rpx, right: 30.rpx),
child: getOnePicker(context, years, yearIndex,
(d) {
yearIndex = d;
dayIndex = 0;
day_len =
DateTime.fromMillisecondsSinceEpoch(
DateTime(
years[yearIndex],
months[monthIndex] +
1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value =
days.sublist(0, day_len);
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 30.rpx),
child: getOnePicker(
context, months, monthIndex, (d) {
monthIndex = d;
dayIndex = 0;
day_len =
DateTime.fromMillisecondsSinceEpoch(
DateTime(
years[yearIndex],
months[monthIndex] +
1)
.millisecondsSinceEpoch -
1000)
.day;
days_select.value =
days.sublist(0, day_len);
}),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 40.rpx),
child: Obx(
() {
// print("${dayIndex} ${day_len}");
return getOnePicker(
context,
days_select,
dayIndex,
(d) {
dayIndex = d;
},
);
},
),
),
),
Container(
child: Text(
"",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
),
),
],
),
),
),
],
),
),
),
),
),
],
);
},
);
}
getOnePicker(context, List arr, int checkIndex, Function onSelectedItemChanged,
{bool looping = false}) {
return CupertinoPicker(
key: UniqueKey(),
useMagnifier: false,
itemExtent: 80.rpx,
magnification: 1,
diameterRatio: 3,
squeeze: 1,
looping: looping,
scrollController: FixedExtentScrollController(initialItem: checkIndex),
selectionOverlay: Container(),
onSelectedItemChanged: (int value) {
// print("$value");
onSelectedItemChanged.call(value);
},
children: [
...List.generate(arr.length, (index) {
return Container(
alignment: Alignment.center,
width: 400.rpx,
decoration: BoxDecoration(
// border: Border(
// bottom: index != arr.length
// ? BorderSide(
// color: stringToColor("#8D95B0"),
// )
// : BorderSide.none,
// ),
),
child: Text("${arr[index]}",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx)),
);
})
],
);
}

View File

@@ -2,7 +2,9 @@ import 'package:flutter/cupertino.dart';
import 'package:vbvs_app/pages/device_bind/bind_device_success.dart'; import 'package:vbvs_app/pages/device_bind/bind_device_success.dart';
import 'package:vbvs_app/pages/device_bind/blueteeth_device_page.dart'; import 'package:vbvs_app/pages/device_bind/blueteeth_device_page.dart';
import 'package:vbvs_app/pages/device_bind/device_type.dart'; import 'package:vbvs_app/pages/device_bind/device_type.dart';
import 'package:vbvs_app/pages/device_bind/wifi_page.dart';
import 'package:vbvs_app/pages/login/login.dart'; import 'package:vbvs_app/pages/login/login.dart';
import 'package:vbvs_app/pages/login/other_login.dart';
import 'package:vbvs_app/pages/main_bottom/e_page.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/home_page.dart';
import 'package:vbvs_app/pages/main_bottom/main_page_bottom_change.dart'; import 'package:vbvs_app/pages/main_bottom/main_page_bottom_change.dart';
@@ -26,6 +28,9 @@ var routes = {
"/blueteethDevice": (contxt) => BlueteethDevicePage(), "/blueteethDevice": (contxt) => BlueteethDevicePage(),
"/personPage": (contxt) => PersonPage(), "/personPage": (contxt) => PersonPage(),
"/bindDeviceSuccess": (contxt) => BindDeviceSuccess(), "/bindDeviceSuccess": (contxt) => BindDeviceSuccess(),
// "/wifiPage": (contxt, {arguments}) => WifiPage(connectedDeviceProp: arguments),
"/wifiPage": (contxt, {arguments}) => WifiPage(bluetoothDevice: arguments),
"/otherLoginPage": (contxt) => OtherLoginPage(),
}; };
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断 //2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断

View File

@@ -31,6 +31,7 @@ dependencies:
lottie: ^3.2.0 lottie: ^3.2.0
flutter_blue_plus: ^1.35.3 flutter_blue_plus: ^1.35.3
permission_handler: ^12.0.0+1 permission_handler: ^12.0.0+1
# geolocator: ^13.0.4
dev_dependencies: dev_dependencies: