This commit is contained in:
wsl
2025-07-01 11:52:25 +08:00
83 changed files with 5526 additions and 3411 deletions

View File

@@ -43,8 +43,8 @@
<application <application
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launchermh"
android:label="太和e护" android:label="眠花糖"
android:enableOnBackInvokedCallback="true" android:enableOnBackInvokedCallback="true"
> >
<activity <activity

View File

@@ -1,5 +1,10 @@
<<<<<<< HEAD
sdk.dir=C:\\Users\\Administrator\\AppData\\Local\\Android\\sdk sdk.dir=C:\\Users\\Administrator\\AppData\\Local\\Android\\sdk
flutter.sdk=C:\\dev\\flutter flutter.sdk=C:\\dev\\flutter
=======
sdk.dir=C:\\Users\\wyf\\AppData\\Local\\Android\\sdk
flutter.sdk=D:\\flutter_res\\flutter
>>>>>>> 13eb25e1c30dcd81c87aa85bcb5306ca0931ed21
flutter.buildMode=debug flutter.buildMode=debug
flutter.versionName=1.0.0 flutter.versionName=1.0.0
flutter.versionCode=1 flutter.versionCode=1

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="30" height="30" viewBox="0 0 30 30"><g><g><g><g></g></g><g><g><g><path d="M15.00048859375,18.657226875C14.87255859375,18.657226875,14.74462859375,18.608396875,14.64648859375,18.510746875C14.64648859375,18.510746875,8.33154259375,12.195312875,8.33154259375,12.195312875C8.13623049375,11.999999875,8.13623049375,11.683593875,8.33154259375,11.488280875C8.52636759375,11.292968775,8.84326159375,11.292968775,9.03857459375,11.488280875C9.03857459375,11.488280875,15.00048859375,17.450196875,15.00048859375,17.450196875C15.00048859375,17.450196875,20.96235859375,11.488280875,20.96235859375,11.488280875C21.15725859375,11.292968775,21.473658593750002,11.292968775,21.66945859375,11.488280875C21.86425859375,11.683593875,21.86425859375,11.999999875,21.66945859375,12.195312875C21.66945859375,12.195312875,15.35351859375,18.510746875,15.35351859375,18.510746875C15.256348593750001,18.608396875,15.12841859375,18.657226875,15.00048859375,18.657226875C15.00048859375,18.657226875,15.00048859375,18.657226875,15.00048859375,18.657226875Z" fill="#333333" fill-opacity="1"/></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -12,164 +12,199 @@
"详情": "详情", "详情": "详情",
"人员资料": "人员资料" "人员资料": "人员资料"
}, },
"请输入手机号":"输入手机号码", "请输入手机号": "输入手机号码",
"请输入正确的手机号":"请输入正确的手机号", "请输入正确的手机号": "请输入正确的手机号",
"请输入密码":"请输入密码", "请输入密码": "请输入密码",
"密码格式提示":"1.密码长度必须至少8位\n2.密码需要字母加数字\n3.特殊字符和大写字母至少包含一个", "密码格式提示": "1.密码长度必须至少8位\n2.密码需要字母加数字\n3.特殊字符和大写字母至少包含一个",
"请输入确认密码":"请输入确认密码", "请输入确认密码": "请输入确认密码",
"两次密码不一致":"两次密码不一致", "两次密码不一致": "两次密码不一致",
"请输入验证码":"请输入验证码", "请输入验证码": "请输入验证码",
"需要同意协议":"需要同意协议", "需要同意协议": "需要同意协议",
"请选择登录方式":"请选择登录方式", "请选择登录方式": "请选择登录方式",
"账户不能为空":"账户不能为空", "账户不能为空": "账户不能为空",
"密码不能为空":"密码不能为空", "密码不能为空": "密码不能为空",
"验证码不能为空":"验证码不能为空", "验证码不能为空": "验证码不能为空",
"密码登录":"密码登录", "密码登录": "密码登录",
"短信登录":"短信登录", "短信登录": "短信登录",
"获取验证码":"获取验证码", "获取验证码": "获取验证码",
"登录":"登录", "登录": "登录",
"找回密码":"找回密码", "找回密码": "找回密码",
"注册":"注册", "注册": "注册",
"我已阅读并同意":"我已阅读并同意", "我已阅读并同意": "我已阅读并同意",
"与":"与", "与": "与",
"《用户协议》":"《用户协议》", "《用户协议》": "《用户协议》",
"《隐私协议》":"《隐私协议》", "《隐私协议》": "《隐私协议》",
"注:首次登录会自动创建账号":"注:首次登录会自动创建账号", "注:首次登录会自动创建账号": "注:首次登录会自动创建账号",
"请输入新密码":"请输入新密码", "请输入新密码": "请输入新密码",
"确认新密码":"确认新密码", "确认新密码": "确认新密码",
"秒":"秒", "秒": "秒",
"添加一台新设备":"添加一台新设备", "添加一台新设备": "添加一台新设备",
"添加新设备":"添加新设备", "添加新设备": "添加新设备",
"网络未连接,请开启设备网络后重试":"网络未连接,请开启设备网络后重试", "网络未连接,请开启设备网络后重试": "网络未连接,请开启设备网络后重试",
"提交":"提交", "提交": "提交",
"发送验证码成功":"发送验证码成功", "发送验证码成功": "发送验证码成功",
"注册成功":"注册成功", "注册成功": "注册成功",
"再按一次退出程序":"再按一次退出程序成功", "再按一次退出程序": "再按一次退出程序成功",
"用户拒绝授权":"用户拒绝授权", "用户拒绝授权": "用户拒绝授权",
"用户取消授权":"用户取消授权", "用户取消授权": "用户取消授权",
"未命名":"未命名", "未命名": "未命名",
"编辑资料":"编辑资料", "编辑资料": "编辑资料",
"保存":"保存", "保存": "保存",
"点击更换头像":"点击更换头像", "点击更换头像": "点击更换头像",
"保存失败":"保存失败", "保存失败": "保存失败",
"昵称为空":"昵称为空", "昵称为空": "昵称为空",
"保存成功":"保存成功", "保存成功": "保存成功",
"请先登录":"请先登录", "请先登录": "请先登录",
"密码修改成功":"密码修改成功", "密码修改成功": "密码修改成功",
"未知数据":"-", "未知数据": "-",
"必须登录提示":"请先登录!", "必须登录提示": "请先登录!",
"输入验证码":"输入验证码", "输入验证码": "输入验证码",
"输入新密码":"输入新密码", "输入新密码": "输入新密码",
"确认验证码":"确认验证码", "确认验证码": "确认验证码",
"输入手机号码":"输入手机号码", "输入手机号码": "输入手机号码",
"操作成功":"操作成功", "操作成功": "操作成功",
"添加设备":"添加设备", "添加设备": "添加设备",
"扫描中":"扫描中...", "扫描中": "扫描中...",
"检索设备":"检索设备", "检索设备": "检索设备",
"搜索":"搜索", "搜索": "搜索",
"匹配出的外围设备":"匹配出的外围设备", "匹配出的外围设备": "匹配出的外围设备",
"知道了":"知道了", "知道了": "知道了",
"蓝牙未开启":"蓝牙未开启", "蓝牙未开启": "蓝牙未开启",
"请先打开蓝牙在进行设备扫描":"请先打开蓝牙在进行设备扫描", "请先打开蓝牙在进行设备扫描": "请先打开蓝牙在进行设备扫描",
"等待扫描":"等待扫描", "等待扫描": "等待扫描",
"默认设备名称":"默认设备名称", "默认设备名称": "默认设备名称",
"连接异常":"连接异常", "连接异常": "连接异常",
"蓝牙绑定提示":"用手机进行设备添加时请打开手机蓝牙搜索靠近目标位置3米以内进行。", "蓝牙绑定提示": "用手机进行设备添加时请打开手机蓝牙搜索靠近目标位置3米以内进行。",
"蓝牙连接成功":"蓝牙连接成功", "蓝牙连接成功": "蓝牙连接成功",
"蓝牙连接失败":"蓝牙连接失败,请重试", "蓝牙连接失败": "蓝牙连接失败,请重试",
"绑定失败请重试":"绑定失败请重试", "绑定失败请重试": "绑定失败请重试",
"无法绑定":"无法绑定!", "无法绑定": "无法绑定!",
"无法绑定1":"检测到该设备", "无法绑定1": "检测到该设备",
"无法绑定2":"已被绑定", "无法绑定2": "已被绑定",
"无法绑定3":",绑定前请先进行解绑,有疑问请联系客服", "无法绑定3": ",绑定前请先进行解绑,有疑问请联系客服",
"蓝牙绑定":{ "蓝牙绑定": {
"标题":"蓝牙绑定", "标题": "蓝牙绑定",
"扫描":"扫描蓝牙设备中…", "扫描": "扫描蓝牙设备中…",
"信号":"最小信号强度", "信号": "最小信号强度",
"搜索提示":"检索设备", "搜索提示": "检索设备",
"搜索":"搜索", "搜索": "搜索",
"匹配":"匹配出的外围设备", "匹配": "匹配出的外围设备",
"信号强度":"信号强度", "信号强度": "信号强度",
"SN":"SN", "SN": "SN",
"蓝牙地址":"蓝牙地址", "蓝牙地址": "蓝牙地址",
"mac":"mac", "mac": "mac",
"网络":"网络", "网络": "网络",
"在线":"在线", "在线": "在线",
"离线":"离线", "离线": "离线",
"版本":"版本", "版本": "版本",
"默认设备名称":"未知设备", "默认设备名称": "未知设备",
"传感器":"传感器", "传感器": "传感器",
"可绑定":"可绑定", "可绑定": "可绑定",
"已被绑定":"已被绑定", "已被绑定": "已被绑定",
"双人版绑定标题":"该设备为双人版,请选择", "双人版绑定标题": "该设备为双人版,请选择",
"绑定全部":"绑定全部", "绑定全部": "绑定全部",
"主设备":"主设备:", "主设备": "主设备:",
"从设备":"从设备:", "从设备": "从设备:",
"确定":"确定", "确定": "确定",
"取消":"取消", "取消": "取消",
"无法绑定":"无法绑定!", "无法绑定": "无法绑定!",
"无法绑定1":"检测到该设备", "无法绑定1": "检测到该设备",
"无法绑定2":"已被绑定", "无法绑定2": "已被绑定",
"无法绑定3":",绑定前请先进行解绑,有疑问请联系客服", "无法绑定3": ",绑定前请先进行解绑,有疑问请联系客服",
"知道了":"知道了", "知道了": "知道了",
"是":"是", "是": "是",
"否":"否", "否": "否",
"确定绑定提示":"确定绑定该设备吗?", "确定绑定提示": "确定绑定该设备吗?",
"连接成功":"蓝牙连接成功", "连接成功": "蓝牙连接成功",
"连接异常":"蓝牙连接异常", "连接异常": "蓝牙连接异常",
"连接":"连接", "连接": "连接",
"输入wifi密码":"请输入wifi密码", "输入wifi密码": "请输入wifi密码",
"显示密码":"显示", "显示密码": "显示",
"不显示密码":"不显示" "不显示密码": "不显示"
}, },
"wifi页":{ "wifi页": {
"标题":"WIFI配置", "标题": "WIFI配置",
"跳过":"下一步", "跳过": "下一步",
"WLAN":"网络", "WLAN": "网络",
"未连接":"未连接", "未连接": "未连接",
"已连接":"已连接", "已连接": "已连接",
"可用WLAN":"可用WLAN", "可用WLAN": "可用WLAN",
"刷新":"刷新", "刷新": "刷新",
"密码为空":"密码不能为空", "密码为空": "密码不能为空",
"配网成功":"配网成功", "配网成功": "配网成功",
"配网失败":"配网失败", "配网失败": "配网失败",
"配网中":"配网中", "配网中": "配网中",
"需配网":"请给设备配置网络!" "需配网": "请给设备配置网络!"
}, },
"设备校准":"设备校准", "设备校准": "设备校准",
"离床校准":"离床校准", "离床校准": "离床校准",
"未完成":"未完成", "未完成": "未完成",
"已完成":"已完成", "已完成": "已完成",
"位置校准":"位置校准", "位置校准": "位置校准",
"床头":"床头", "床头": "床头",
"离床校准提示":"请校准人员暂时离开床铺且在校准期间保持周围安静", "离床校准提示": "请校准人员暂时离开床铺且在校准期间保持周围安静",
"位置校准提示":"请校准人员到箭头指定一侧 平躺后点击开始保持10秒", "位置校准提示": "请校准人员到箭头指定一侧 平躺后点击开始保持10秒",
"开始校准":"开始校准", "开始校准": "开始校准",
"校准完成":"校准完成!", "校准完成": "校准完成!",
"绑定成功":{ "绑定成功": {
"标题":"绑定完成", "标题": "绑定完成",
"绑定成功":"配置成功! ", "绑定成功": "配置成功! ",
"分享标题":"是否进行分享?", "分享标题": "是否进行分享?",
"分享内容":"设备绑定成功后,如需对朋友或家人共享我的睡眠情况,可以进行立即分享,分享成功后,对方即可享受查看该设备权限,可以收到该设备的睡眠报告。", "分享内容": "设备绑定成功后,如需对朋友或家人共享我的睡眠情况,可以进行立即分享,分享成功后,对方即可享受查看该设备权限,可以收到该设备的睡眠报告。",
"立即分享":"立即分享", "立即分享": "立即分享",
"返回":"返回" "返回": "返回"
}, },
"设置页":{ "设置页": {
"标题":"设置", "标题": "设置",
"主题模式":"主题模式", "主题模式": "主题模式",
"选择语言":"选择语言", "选择语言": "选择语言",
"关于我们":"关于我们", "关于我们": "关于我们",
"用户协议":"用户协议", "用户协议": "用户协议",
"隐私协议":"隐私协议", "隐私协议": "隐私协议",
"退出登录":"退出登录", "退出登录": "退出登录",
"注销账号":"注销账号", "注销账号": "注销账号",
"退出成功":"退出成功", "退出成功": "退出成功",
"退出失败":"退出失败" "退出失败": "退出失败"
}, },
"操作成功": "操作成功", "操作成功": "操作成功",
"关于我们": "关于我们", "关于我们": "关于我们",
"用户协议": "用户协议", "用户协议": "用户协议",
"隐私协议": "隐私协议", "隐私协议": "隐私协议",
"退出登录": "退出登录", "退出登录": "退出登录",
"注销账号": "注销账号" "注销账号": "注销账号",
"我的智能设备": "我的智能设备",
"解绑成功": "解绑成功",
"解绑失败": "解绑失败",
"睡眠隐私": "睡眠隐私",
"睡眠隐私功能": "睡眠隐私功能",
"开始时间": "开始时间",
"结束时间": "结束时间",
"取消": "取消",
"确认": "确认",
"时": "时",
"分": "分",
"选择性别": "选择性别",
"*注:开启睡眠隐私功能后,在设置的时间段内,将不会采集您的睡眠数据。": "*注:开启睡眠隐私功能后,在设置时间段内,将不会采集您的睡眠数据。",
"柔性唤醒": "柔性唤醒",
"睡眠银色": "睡眠隐私",
"睡眠习惯": "睡眠习惯",
"允许对方查看设备": "允许对方查看设备",
"允许对方控制设备": "允许对方控制设备",
"已分享用户": "已分享用户",
"发送邀请": "发送邀请",
"仅允许对方查看该设备": "仅允许对方查看该设备",
"允许对方控制该设备": "允许对方控制该设备",
"点击复制APP下载链接": "点击复制APP下载链接",
"评价": "评价",
"我要评价": "我要评价",
"更新成功": "更新成功",
"更新失败": "更新失败",
"完成": "完成",
"请输入正确的联系人电话": "请输入正确的联系人电话",
"请选择体重": "请输入体重",
"请选择身高": "请输入身高",
"人员资料": "人员资料",
"请输入姓名": "请输入姓名",
"解除分享":"解除分享"
} }

View File

@@ -2,8 +2,9 @@ import 'dart:ui';
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/enum/APPPackageType.dart';
class AppConstants { class AppConstants {
// App-related constants // App-related constants
static const int code_time = 60; //验证码倒计时 static const int code_time = 60; //验证码倒计时
static const int limit = 10; //分页数量 static const int limit = 10; //分页数量
@@ -46,5 +47,6 @@ class AppConstants {
]; ];
//系统参数 //系统参数
int ent_type = 1;//1.默认太和 2.欢睡 //运行打包APP模式
int ent_type = APPPackageType.TH.code;//1.默认太和 2.欢睡 3.眠花糖
} }

View File

@@ -26,26 +26,30 @@ class DailyLogUtils {
// 写入 info 日志(原 writeLog 保留) // 写入 info 日志(原 writeLog 保留)
static Future<void> writeLog(String content) async { static Future<void> writeLog(String content) async {
print("[dailylog-->info] $content]");
await _writeLogWithLevel('INFO', content); await _writeLogWithLevel('INFO', content);
} }
// 写入 warning 日志 // 写入 warning 日志
static Future<void> writeWarning(String content) async { static Future<void> writeWarning(String content) async {
print("[dailylog-->waring] $content]");
await _writeLogWithLevel('WARNING', content); await _writeLogWithLevel('WARNING', content);
} }
// 写入 error 日志 // 写入 error 日志
static Future<void> writeError(String content) async { static Future<void> writeError(String content) async {
print("[dailylog-->error] $content]");
await _writeLogWithLevel('ERROR', content); await _writeLogWithLevel('ERROR', content);
} }
// 写入 debug 日志 // 写入 debug 日志
static Future<void> writeDebug(String content) async { static Future<void> writeDebug(String content) async {
print("[dailylog-->debug] $content]");
await _writeLogWithLevel('DEBUG', content); await _writeLogWithLevel('DEBUG', content);
} }
static Future<void> printLog(String content) async { static Future<void> printLog(String content) async {
print("logger--->"+content); print("logger--->" + content);
// await writeLog(content); // await writeLog(content);
} }

View File

@@ -382,7 +382,7 @@ var returnIconButtom = IconButton(
var returnIconButtomNew = ClickableContainer( var returnIconButtomNew = ClickableContainer(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0), padding: EdgeInsets.fromLTRB(20.rpx, 20.rpx, 20.rpx, 20.rpx),
onTap: () => Get.back(), onTap: () => Get.back(),
child: Container( child: Container(
// height: 42.rpx, // height: 42.rpx,

View File

@@ -31,10 +31,11 @@ class SleepdateWidget extends StatelessWidget {
color: isSelected ? highlightColor : Colors.transparent, // 使用传入的颜色 color: isSelected ? highlightColor : Colors.transparent, // 使用传入的颜色
), ),
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx), padding:
EdgeInsetsDirectional.fromSTEB(10.rpx, 10.rpx, 10.rpx, 10.rpx),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFFDC1C1C), color: Color(0xFF757575),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
alignment: Alignment.center, alignment: Alignment.center,

View File

@@ -52,16 +52,16 @@ class DeviceShareController extends GetControllerEx<DeviceShareModel> {
String serviceApi = ServiceConstant.device_type; String serviceApi = ServiceConstant.device_type;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
} }
} }
var response = await EasyDartModule.dio.get(queryUrl); var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) { if (response != null) {
var responseData = var responseData =
@@ -100,16 +100,16 @@ class DeviceShareController extends GetControllerEx<DeviceShareModel> {
String serviceApi = ServiceConstant.device_share; String serviceApi = ServiceConstant.device_share;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
var data = {"type": 1, "userName": account.value, "mac": mac}; var data = {"type": 1, "userName": account.value, "mac": mac};
var response = var response =
await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data)); await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data));
@@ -158,16 +158,16 @@ class DeviceShareController extends GetControllerEx<DeviceShareModel> {
String serviceApi = ServiceConstant.device_share; String serviceApi = ServiceConstant.device_share;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = ""; String? language = "";
if (languageController.selectLanguage != null) { if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code; language = languageController.selectLanguage.value!.language_code;
} }
if (language != null && language.isNotEmpty) { if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) { if (queryUrl.contains("?")) {
queryUrl += "&lang=$language"; queryUrl += "&lang=$language";
} else { } else {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
}
} }
}
final data = { final data = {
"code": shareCode, "code": shareCode,
}; };

View File

@@ -3,13 +3,14 @@ import 'package:flutter/material.dart';
import 'package:flutter_city_picker/model/address.dart'; import 'package:flutter_city_picker/model/address.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:lpinyin/lpinyin.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/user_data.dart'; import 'package:vbvs_app/model/user_data.dart';
import 'package:lpinyin/lpinyin.dart'; // import 'package:lpinyin/lpinyin.dart';
part 'address_controller.g.dart'; part 'address_controller.g.dart';
@JsonSerializable() @JsonSerializable()
@@ -209,6 +210,7 @@ class AddressController extends GetControllerEx<AddressModel> {
// 工具:中文首字母转大写英文(你也可以用更专业的拼音库) // 工具:中文首字母转大写英文(你也可以用更专业的拼音库)
String _getLetter(String name) { String _getLetter(String name) {
// return name;
if (name.isEmpty) return "#"; if (name.isEmpty) return "#";
String pinyin = PinyinHelper.getPinyinE(name, String pinyin = PinyinHelper.getPinyinE(name,
separator: '', defPinyin: '', format: PinyinFormat.WITHOUT_TONE); separator: '', defPinyin: '', format: PinyinFormat.WITHOUT_TONE);

View File

@@ -8,6 +8,7 @@ import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/controller/mh_controller/device.dart'; import 'package:vbvs_app/controller/mh_controller/device.dart';
import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/model/api_response.dart';
@@ -19,7 +20,6 @@ class DeviceListModel {
//设备列表 //设备列表
List<dynamic> deviceList = []; List<dynamic> deviceList = [];
@JsonKey(ignore: true) @JsonKey(ignore: true)
String? keyword; String? keyword;
@JsonKey(ignore: true) @JsonKey(ignore: true)
@@ -39,8 +39,8 @@ class DeviceListController extends GetControllerEx<DeviceListModel> {
getDeviceList() async { getDeviceList() async {
try { try {
String search = (model.keyword != null && model.keyword!.isNotEmpty) String search = (model.keyword != null && model.keyword!.isNotEmpty)
? "?key=${model.keyword}" ? "?key=${model.keyword}&ncs=1"
: ""; : "?ncs=1";
ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr); ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr);
String serviceAddress = ServiceConstant.service_address; String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service; String serviceName = ServiceConstant.server_service;
@@ -70,4 +70,35 @@ class DeviceListController extends GetControllerEx<DeviceListModel> {
} }
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
} }
//主动解绑设备
Future<String> unbindDevice(Map<dynamic, dynamic> device) async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_bind;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String msg = '';
int type = device['bind_type'];
await requestWithLog(
logTitle: '解绑设备',
method: MyHttpMethod.delete,
queryUrl: queryUrl,
data: {"mac": device['mac']},
onSuccess: (res) {
if (type == 1) {
msg = '解绑成功'.tr;
} else {
msg = '删除成功'.tr;
}
},
onFailure: (res) {
if (type == 1) {
msg = '解绑失败'.tr;
} else {
msg = '删除失败'.tr;
}
},
);
return msg;
}
} }

View File

@@ -1,19 +1,28 @@
import 'dart:convert';
import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:dio/src/form_data.dart' as formdata; import 'package:dio/src/form_data.dart' as formdata;
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/model/api_response.dart';
part 'mhdevice_share_controller.g.dart'; part 'mhdevice_share_controller.g.dart';
@JsonSerializable() @JsonSerializable()
class MHDeviceShareModel { class MHDeviceShareModel {
String? phone; String? account;
int? type = 1; int? type = 1;
String? msg; String? msg;
int? show = 0; int? show = 0;
int? code = 0;
int limit = AppConstants.limit; int limit = AppConstants.limit;
int offset = 0; int offset = 0;
bool isLoading = false; bool isLoading = false;
@@ -37,86 +46,142 @@ class MHDeviceShareController extends GetControllerEx<MHDeviceShareModel> {
attr = GetModel(MHDeviceShareModel()).obs; attr = GetModel(MHDeviceShareModel()).obs;
} }
// RxString account = "".obs;
// RxString msg = "".obs;
// RxInt code = 0.obs;
@override @override
void onInit() { Future<void> onInit() async {
super.onInit(); super.onInit();
model.shareUser = [ await shareDeviceList(Get.arguments["mac"]);
{
'userName': '张三',
'opType': 1, // 允许控制
},
{
'userName': '李四',
'opType': 2, // 仅查看
},
{
'userName': '王五',
'opType': 1,
},
];
update(); // 刷新UI
} }
// Future<String> sendInvite(String? phone, String mac) async { Future<ApiResponse> shareDevice(String mac) async {
// if (phone == null || phone.isEmpty) { ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
// return "手机号不能为空"; EasyDartModule.logger.info("分享设备");
// } DailyLogUtils.writeLog("分享设备");
// if (!MyUtils.isValidPhoneNumber(phone)) { try {
// return "手机号格式不正确"; model.account = model.account!.trim();
// } if (model.account == null || model.account!.isEmpty) {
// var type = model.type; apiResponse.msg = "请输入手机号".tr;
// try { return apiResponse;
// var aa = await ApiService.requestNoInfo.post("/api/device/info/share", }
// data: formdata.FormData.fromMap( if (!MyUtils.isValidPhoneNumber(model.account!) &&
// {"mac": mac, "tel": phone, "type": type})); !MyUtils.isValidEmail(model.account!)) {
// return ""; apiResponse.msg = '请输入正确的手机号/邮箱号'.tr;
// } catch (e) { return apiResponse;
// if (e is DioError) { }
// // 返回 DioError 的 message 属性 String serviceAddress = ServiceConstant.service_address;
// return e.message!; String serviceName = ServiceConstant.server_service;
// } else { String serviceApi = ServiceConstant.device_share;
// // 处理其他类型的错误 String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
// return e.toString(); String? language = "";
// } if (languageController.selectLanguage != null) {
// } language = languageController.selectLanguage.value!.language_code;
// } }
if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) {
queryUrl += "&lang=$language";
} else {
queryUrl += "?lang=$language";
}
}
var data = {"type": model.type, "userName": model.account, "mac": mac};
var response =
await EasyDartModule.dio.post(queryUrl, data: jsonEncode(data));
if (response != null) {
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
if (res.code != HttpStatusCodes.ok) {
if (res.msg == null || res.msg!.isEmpty) {
res.msg = apiResponse.msg;
}
} else {
if (res.msg == null || res.msg!.isEmpty) {
res.msg = "操作成功".tr;
}
}
if (res.code != HttpStatusCodes.ok) {
model.msg = res.msg!;
}
model.code = res.code!;
updateAll();
return res;
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
} catch (e) {
EasyDartModule.logger.info("分享设备失败:${e.toString()}");
DailyLogUtils.writeLog("分享设备失败:${e.toString()}");
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
}
// Future<void> initData() async { shareDeviceList(String mac) async {
// //todo 请求分享列表 String serviceAddress = ServiceConstant.service_address;
// var deviceController = Get.find<GlobalController>(); String serviceName = ServiceConstant.server_service;
// var query = { String serviceApi = ServiceConstant.device_share;
// "mac": deviceController.model.deviceMain['mac'], String queryUrl = "${serviceAddress}${serviceName}${serviceApi}?mac=$mac";
// }; await requestWithLog(
// var data = await ApiService.request logTitle: '分享用户列表',
// .get("/api/device/info/share", data: formdata.FormData.fromMap(query)); method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) => {
model.shareUser = res.data,
updateAll(),
},
);
}
// if (data.data["data"] != null) { Future<ApiResponse> confirmShare(String shareCode) async {
// try { EasyDartModule.logger.info("确认消息分享");
// List<dynamic> tmp = data.data["data"] as List<dynamic>; DailyLogUtils.writeLog("确认消息分享");
// model.shareUser = tmp; try {
// } catch (e) { ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
// print(e); if (shareCode == null || shareCode.isEmpty) {
// } apiResponse.msg = "请求失败".tr;
// } else { return apiResponse;
// model.shareUser = []; }
// } String serviceAddress = ServiceConstant.service_address;
// updateAll(); String serviceName = ServiceConstant.server_service;
// } String serviceApi = ServiceConstant.device_share;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
// //保存 String? language = "";
// saveShareDevice(Map shareInfo, RxInt type) async { if (languageController.selectLanguage != null) {
// return await ApiService.request.put("/api/device/info/share", language = languageController.selectLanguage.value!.language_code;
// data: formdata.FormData.fromMap({ }
// "mac": shareInfo['mac'], if (language != null && language.isNotEmpty) {
// "tel": shareInfo['tel'], if (queryUrl.contains("?")) {
// "type": type.value queryUrl += "&lang=$language";
// })); } else {
// } queryUrl += "?lang=$language";
}
// //删除 }
// deleteShare(Map shareInfo) async { final data = {
// return await ApiService.request.delete("/api/device/info/share", "code": shareCode,
// data: formdata.FormData.fromMap( };
// {"mac": shareInfo['mac'], "tel": shareInfo['tel']})); var response =
// } await EasyDartModule.dio.put(queryUrl, data: jsonEncode(data));
if (response != null) {
if (response.data['code'] != HttpStatusCodes.ok) {
apiResponse.msg = response.data['msg'];
apiResponse.code = response.data['code'];
return apiResponse;
}
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
MyUtils.formatResponse(res, "操作成功".tr, "操作失败".tr);
return res;
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
} catch (e) {
EasyDartModule.logger.info("确认消息分享失败->$e");
DailyLogUtils.writeLog("确认消息分享失败->$e");
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
}
} }

View File

@@ -8,10 +8,11 @@ part of 'mhdevice_share_controller.dart';
MHDeviceShareModel _$MHDeviceShareModelFromJson(Map<String, dynamic> json) => MHDeviceShareModel _$MHDeviceShareModelFromJson(Map<String, dynamic> json) =>
MHDeviceShareModel() MHDeviceShareModel()
..phone = json['phone'] as String? ..account = json['account'] as String?
..type = (json['type'] as num?)?.toInt() ..type = (json['type'] as num?)?.toInt()
..msg = json['msg'] as String? ..msg = json['msg'] as String?
..show = (json['show'] as num?)?.toInt() ..show = (json['show'] as num?)?.toInt()
..code = (json['code'] as num?)?.toInt()
..limit = (json['limit'] as num).toInt() ..limit = (json['limit'] as num).toInt()
..offset = (json['offset'] as num).toInt() ..offset = (json['offset'] as num).toInt()
..isLoading = json['isLoading'] as bool ..isLoading = json['isLoading'] as bool
@@ -21,10 +22,11 @@ MHDeviceShareModel _$MHDeviceShareModelFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> _$MHDeviceShareModelToJson(MHDeviceShareModel instance) => Map<String, dynamic> _$MHDeviceShareModelToJson(MHDeviceShareModel instance) =>
<String, dynamic>{ <String, dynamic>{
'phone': instance.phone, 'account': instance.account,
'type': instance.type, 'type': instance.type,
'msg': instance.msg, 'msg': instance.msg,
'show': instance.show, 'show': instance.show,
'code': instance.code,
'limit': instance.limit, 'limit': instance.limit,
'offset': instance.offset, 'offset': instance.offset,
'isLoading': instance.isLoading, 'isLoading': instance.isLoading,

View File

@@ -39,7 +39,7 @@ class RepairListController extends GetControllerEx<RepairListModel> {
String serviceName = ServiceConstant.server_service; String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.submit_repair; String serviceApi = ServiceConstant.submit_repair;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
requestWithLog( await requestWithLog(
logTitle: "查询报修数据", logTitle: "查询报修数据",
method: MyHttpMethod.get, method: MyHttpMethod.get,
queryUrl: queryUrl, queryUrl: queryUrl,

View File

@@ -12,9 +12,7 @@ RepairListModel _$RepairListModelFromJson(Map<String, dynamic> json) =>
..offset = (json['offset'] as num).toInt() ..offset = (json['offset'] as num).toInt()
..isLoading = json['isLoading'] as bool ..isLoading = json['isLoading'] as bool
..hasMore = json['hasMore'] as bool ..hasMore = json['hasMore'] as bool
..repairList = (json['repairList'] as List<dynamic>) ..repairList = json['repairList'] as List<dynamic>;
.map((e) => ApplyRepairModel.fromJson(e as Map<String, dynamic>))
.toList();
Map<String, dynamic> _$RepairListModelToJson(RepairListModel instance) => Map<String, dynamic> _$RepairListModelToJson(RepairListModel instance) =>
<String, dynamic>{ <String, dynamic>{

View File

@@ -0,0 +1,11 @@
enum APPPackageType {
TH(1, '太和'),
HUANSHUI(2, '欢睡'),
MHT(3, '眠花糖'),
;
final int code;
final String description;
const APPPackageType(this.code, this.description);
}

View File

@@ -12,7 +12,6 @@ import 'package:fluwx/fluwx.dart';
import 'package:get_storage/get_storage.dart'; import 'package:get_storage/get_storage.dart';
import 'package:localstorage/localstorage.dart'; import 'package:localstorage/localstorage.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart'; import 'package:syncfusion_localizations/syncfusion_localizations.dart';
import 'package:vbvs_app/common/color/AppGlobal.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/util/CheckNetwork.dart'; import 'package:vbvs_app/common/util/CheckNetwork.dart';
import 'package:vbvs_app/common/util/CommonVariables.dart'; import 'package:vbvs_app/common/util/CommonVariables.dart';
@@ -194,8 +193,6 @@ void initEasyDartModule() {
//初始化 //初始化
} }
Future<void> initLogin() async { Future<void> initLogin() async {
// 初始化控制器 // 初始化控制器
Get.put(UserInfoController()); Get.put(UserInfoController());
@@ -358,6 +355,8 @@ class MyApp extends StatelessWidget {
Get.lazyPut(() => MHTDeviceCalibrationController()), Get.lazyPut(() => MHTDeviceCalibrationController()),
Get.lazyPut(() => SleepReportController()), Get.lazyPut(() => SleepReportController()),
Get.lazyPut(() => CalendarController()), Get.lazyPut(() => CalendarController()),
Get.lazyPut(() => UserPdfController()),
Get.lazyPut(() => PrivacyPdfController()),
Get.put(WebviewTestController()), Get.put(WebviewTestController()),
])); ]));
} }

View File

@@ -714,13 +714,13 @@ Future showDayTimeSelectionDialog(
width: 100.rpx, width: 100.rpx,
height: 60.rpx, height: 60.rpx,
alignment: Alignment.center, alignment: Alignment.center,
child: Text("取消", child: Text("取消".tr,
style: TextStyle( style: TextStyle(
fontSize: 30.rpx, color: Colors.white)), fontSize: 30.rpx, color: Colors.white)),
), ),
), ),
Text( Text(
title, title.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
@@ -742,7 +742,7 @@ Future showDayTimeSelectionDialog(
width: 100.rpx, width: 100.rpx,
height: 60.rpx, height: 60.rpx,
alignment: Alignment.center, alignment: Alignment.center,
child: Text("确认", child: Text("确认".tr,
style: TextStyle( style: TextStyle(
fontSize: 30.rpx, color: Colors.white)), fontSize: 30.rpx, color: Colors.white)),
), ),
@@ -778,7 +778,7 @@ Future showDayTimeSelectionDialog(
context, context,
hours, hours,
hoursIndex, hoursIndex,
unit: "", unit: "".tr,
), ),
), ),
Expanded( Expanded(
@@ -786,7 +786,7 @@ Future showDayTimeSelectionDialog(
context, context,
minutes, minutes,
minutesIndex, minutesIndex,
unit: "", unit: "".tr,
), ),
), ),
], ],
@@ -856,12 +856,12 @@ Future showOneSelectionDialog(
alignment: Alignment.center, alignment: Alignment.center,
width: 100.rpx, width: 100.rpx,
height: 60.rpx, height: 60.rpx,
child: Text("取消", child: Text("取消".tr,
style: TextStyle( style: TextStyle(
fontSize: 30.rpx, color: Colors.white)), fontSize: 30.rpx, color: Colors.white)),
), ),
), ),
Text(title, Text(title.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Colors.white, color: Colors.white,
@@ -879,7 +879,7 @@ Future showOneSelectionDialog(
alignment: Alignment.center, alignment: Alignment.center,
width: 100.rpx, width: 100.rpx,
height: 60.rpx, height: 60.rpx,
child: Text("确认", child: Text("确认".tr,
style: TextStyle( style: TextStyle(
fontSize: 30.rpx, color: Colors.white)), fontSize: 30.rpx, color: Colors.white)),
), ),

View File

@@ -1128,3 +1128,235 @@ Future<void> showUnBindTipDialog(
}, },
); );
} }
Future<void> showUnbindConfirmDialog({
required BuildContext context,
required VoidCallback onConfirm,
required VoidCallback onCancel,
required String title,
}) async {
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return FrostedDialog(
blurSigma: 3.0,
child: Container(
width: 520.rpx,
height: 460.rpx,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.0),
),
child: Padding(
padding: EdgeInsets.only(
left: 45.rpx, right: 45.rpx, top: 90.rpx, bottom: 60.rpx),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.black,
),
),
const SizedBox(height: 12),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(fontSize: 26.rpx, color: Colors.black87),
children: [
TextSpan(
text: '该设备只可被一个用户绑定,',
style: TextStyle(fontSize: 26.rpx)),
TextSpan(
text: '解绑后',
style: TextStyle(color: Colors.red, fontSize: 26.rpx),
),
TextSpan(
text: '其他用户才可以绑定',
style: TextStyle(fontSize: 26.rpx)),
],
),
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CustomCard(
gradientDirection: GradientDirection.vertical,
borderRadius: 16.rpx,
onTap: () {
Get.back();
onCancel();
},
colors: [
Color(0xFF1592AA),
Color(0XFF0C83A7),
Color(0XFF006FA3)
],
child: Container(
width: 200.rpx,
height: 90.rpx,
alignment: Alignment.center,
child: Text(
'取消',
style: TextStyle(
fontSize: 26.rpx, color: Colors.white),
),
)),
CustomCard(
borderRadius: 16.rpx,
onTap: () {
Get.back();
onConfirm();
},
colors: [
Color(0xFF1592AA),
Color(0XFF0C83A7),
Color(0XFF006FA3)
],
child: Container(
width: 200.rpx,
height: 90.rpx,
alignment: Alignment.center,
child: Text(
'解绑',
style: TextStyle(
fontSize: 26.rpx, color: Colors.white),
),
))
// _buildButton(
// text: '解绑',
// onPressed: () {
// Navigator.pop(context);
// onConfirm();
// },
// isGradient: true,
// ),
],
)
],
),
),
));
},
);
}
Future<void> showDeleteDeviceConfirmDialog({
required BuildContext context,
required VoidCallback onConfirm,
required VoidCallback onCancel,
required String title,
}) async {
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return FrostedDialog(
blurSigma: 3.0,
child: Container(
width: 520.rpx,
height: 460.rpx,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.0),
),
child: Padding(
padding: EdgeInsets.only(
left: 45.rpx, right: 45.rpx, top: 90.rpx, bottom: 60.rpx),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.black,
),
),
const SizedBox(height: 12),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(fontSize: 26.rpx, color: Colors.black87),
children: [
TextSpan(
text: '删除后,',
style:
TextStyle(color: Colors.red, fontSize: 26.rpx)),
TextSpan(
text: '该设备的历史数据将被清除',
style: TextStyle(fontSize: 26.rpx),
),
],
),
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CustomCard(
gradientDirection: GradientDirection.vertical,
borderRadius: 16.rpx,
onTap: () {
Get.back();
onCancel();
},
colors: [
Color(0xFF1592AA),
Color(0XFF0C83A7),
Color(0XFF006FA3)
],
child: Container(
width: 200.rpx,
height: 90.rpx,
alignment: Alignment.center,
child: Text(
'取消',
style: TextStyle(
fontSize: 26.rpx, color: Colors.white),
),
)),
CustomCard(
borderRadius: 16.rpx,
onTap: () {
Get.back();
onConfirm();
},
colors: [
Color(0xFF1592AA),
Color(0XFF0C83A7),
Color(0XFF006FA3)
],
child: Container(
width: 200.rpx,
height: 90.rpx,
alignment: Alignment.center,
child: Text(
'删除',
style: TextStyle(
fontSize: 26.rpx, color: Colors.white),
),
))
// _buildButton(
// text: '解绑',
// onPressed: () {
// Navigator.pop(context);
// onConfirm();
// },
// isGradient: true,
// ),
],
)
],
),
),
));
},
);
}

View File

@@ -1,12 +1,32 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart';
import 'package:vbvs_app/pages/mh_page/MattressControl.dart'; import 'package:vbvs_app/pages/mh_page/MattressControl.dart';
import 'package:vbvs_app/pages/mh_page/device_list.dart';
import 'package:vbvs_app/pages/mh_page/homepage/mht_sleep_report_page.dart'; import 'package:vbvs_app/pages/mh_page/homepage/mht_sleep_report_page.dart';
import 'package:vbvs_app/pages/mh_page/homepage/new_Home_page.dart'; import 'package:vbvs_app/pages/mh_page/homepage/new_Home_page.dart';
import 'package:vbvs_app/pages/mh_page/new_mine_page.dart'; import 'package:vbvs_app/pages/mh_page/new_mine_page.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class MainPageBBottomChange extends StatefulWidget { class MainPageBBottomChange extends StatefulWidget {
// 全局 key用于静态访问 _HomePageState
static final GlobalKey<_HomePageState> globalKey =
GlobalKey<_HomePageState>();
MainPageBBottomChange({Key? key}) : super(key: globalKey);
// 静态方法:外部调用,跳转 tab
static void jumpTo(int index) {
final state = globalKey.currentState;
if (state != null) {
state.switchTab(index);
}
}
static int? getCurrentIndex() {
final state = globalKey.currentState;
return state?.selectedIndex;
}
@override @override
_HomePageState createState() => _HomePageState(); _HomePageState createState() => _HomePageState();
} }
@@ -55,6 +75,7 @@ class _HomePageState extends State<MainPageBBottomChange>
void _onTabTapped(int index) { void _onTabTapped(int index) {
setState(() { setState(() {
dealWebSource(index);
final begin = currentPosition; final begin = currentPosition;
final end = index.toDouble(); final end = index.toDouble();
_positionAnimation = Tween<double>(begin: begin, end: end).animate( _positionAnimation = Tween<double>(begin: begin, end: end).animate(
@@ -95,4 +116,31 @@ class _HomePageState extends State<MainPageBBottomChange>
), ),
); );
} }
void switchTab(int index) {
final begin = currentPosition;
final end = index.toDouble();
_positionAnimation = Tween<double>(begin: begin, end: end).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeOut),
)..addListener(() {
setState(() {});
});
_controller.forward(from: 0.0);
currentPosition = end;
setState(() {
selectedIndex = index;
});
}
Future<void> dealWebSource(int index) async {
WebviewTestController webviewTestController = Get.find();
if (index == 2) {
await webviewTestController.web.jsbridge?.dart.pageActive();
} else {
await webviewTestController.web.jsbridge?.dart.pageInActive();
}
}
} }

View File

@@ -49,7 +49,7 @@ class _BackMovementPageState extends State<BackMovementPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -58,7 +58,7 @@ class _HomeDeviceTypeState extends State<HomeDeviceType> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtom, child: returnIconButtom,
), ),
], ],

View File

@@ -12,16 +12,16 @@ class LanguagePage extends GetView<MHLanguageController> {
// } // }
MHLanguageController controller = Get.find(); MHLanguageController controller = Get.find();
BoxConstraints? bodysize; BoxConstraints? bodysize;
List<String> languageList = [ // List<String> languageList = [
'简体中文', // '简体中文',
'繁體中文', // '繁體中文',
'English', // 'English',
]; // ];
final Map<String, String> languageMap = { // final Map<String, String> languageMap = {
'简体中文': 'zh_CN', // '简体中文': 'zh_CN',
'繁體中文': 'zh_TW', // '繁體中文': 'zh_TW',
'English': 'en_US', // 'English': 'en_US',
}; // };
// class _LanguagePageState extends State<LanguagePage> { // class _LanguagePageState extends State<LanguagePage> {
RxBool checkboxValue = false.obs; RxBool checkboxValue = false.obs;
@@ -56,7 +56,7 @@ class LanguagePage extends GetView<MHLanguageController> {
children: [ children: [
// 中间居中的标题 // 中间居中的标题
Text( Text(
'切换语言', '切换语言'.tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@@ -135,7 +135,7 @@ class LanguagePage extends GetView<MHLanguageController> {
value: controller.selectLanguage.value?.language_code == value: controller.selectLanguage.value?.language_code ==
model.language_code, model.language_code,
onChanged: (newValue) async { onChanged: (newValue) async {
controller.selectLanguage.value = model; controller.selectLanguage.value = model;
// if (newValue!) { // if (newValue!) {
// selectLanguage!.value = languageMap[ // selectLanguage!.value = languageMap[
// text]!; // Set selectLanguage to the current text value // text]!; // Set selectLanguage to the current text value

View File

@@ -3,8 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:flutter_switch/flutter_switch.dart'; import 'package:flutter_switch/flutter_switch.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/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart'; import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class MattressControlPage extends StatefulWidget { class MattressControlPage extends StatefulWidget {
@@ -17,35 +15,6 @@ class MattressControlPage extends StatefulWidget {
class _MattressControlPageState extends State<MattressControlPage> { class _MattressControlPageState extends State<MattressControlPage> {
final controller = Get.put(ControlCardController()); final controller = Get.put(ControlCardController());
final data = {
"_id": "333330000000000000000000",
"uid": "684b90df767e00004e0072e2",
"bind_type": 1,
"device_type": 3,
"mac": "545024122666",
"bind_mac": null,
"bind_mac_a": "B43A45C3D411",
"bind_mac_b": "B43A45C3D388",
"position": 0,
"share_uid": null,
"person": null,
"op_type": null,
"show": true,
"create_time": 1750121686274,
"room_id": "684395bf9ef8601da20f6475",
"roomName": "主卧",
"shareNum": 0,
"status": {
"signal": -1,
"status": 0,
"inBed": 0,
"upgrade": 0,
"failure": 0,
"updateTime": -1
},
"code": "545024122666",
"blueToothStatus": 1
};
int selectedIndex = 1; // 当前选中的tab索引 int selectedIndex = 1; // 当前选中的tab索引
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -138,10 +107,10 @@ class _MattressControlPageState extends State<MattressControlPage> {
body: SafeArea( body: SafeArea(
child: WebviewTestView( child: WebviewTestView(
oncreate: (widget) { // oncreate: (widget) {
return WebviewTestController(); // return WebviewTestController();
}, // },
), ),
), ),
)))); ))));
} }

View File

@@ -39,7 +39,7 @@ class _MhMessageListWidgetState extends State<MhMessageListWidget> {
highlightColor: Color(0xFF055466), highlightColor: Color(0xFF055466),
borderRadius: 20.rpx, borderRadius: 20.rpx,
padding: padding:
EdgeInsetsDirectional.fromSTEB(31.rpx, 33.rpx, 0.rpx, 33.rpx), EdgeInsetsDirectional.fromSTEB(31.rpx, 33.rpx, 26.rpx, 26.rpx),
onTap: () {}, onTap: () {},
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@@ -95,66 +95,65 @@ class _MhMessageListWidgetState extends State<MhMessageListWidget> {
), ),
].divide(SizedBox(width: 30.rpx)), ].divide(SizedBox(width: 30.rpx)),
), ),
], if (messageInfo['type'] == 'app_system')
),
), // // right: 26.rpx,
if (messageInfo['type'] == 'app_system') // left: 26.rpx,
Positioned( Container(
bottom: 46.rpx, // width: 123.rpx,
right: 20.rpx, height: 61.rpx,
child: Container( child: CustomCard(
width: 123.rpx, borderRadius: 16.rpx, // 直角
height: 47.rpx, gradientDirection: GradientDirection.vertical,
child: CustomCard( colors: [Color(0xFF84F5FF)],
borderRadius: AppConstants().button_container_radius, // 直角 enableAnimation: true, // 有点击缩放动画
colors: messageInfo['status'] == 1 enableGradient: false, // 不用渐变
? [ onTap: () {
themeController.currentColor.sc1, // if (messageInfo['status'] == 1) {
themeController.currentColor.sc2 // showConfirmDialog(
] // context, Container(), "是否确认接受该设备".tr,
: [themeController.currentColor.sc4], // 单色背景 // onConfirm: () async {
enableAnimation: true, // 有点击缩放动画 // ApiResponse apiResponse =
enableGradient: false, // 不用渐变 // await deviceShareController.confirmShare(
onTap: () { // messageInfo['data']['shareCode']);
if (messageInfo['status'] == 1) { // if (apiResponse.code == HttpStatusCodes.ok) {
showConfirmDialog(context, Container(), "是否确认接受该设备".tr, // TopSlideNotification.show(
onConfirm: () async { // context,
ApiResponse apiResponse = await deviceShareController // text: apiResponse.msg!,
.confirmShare(messageInfo['data']['shareCode']); // textColor: themeController.currentColor.sc2,
if (apiResponse.code == HttpStatusCodes.ok) { // );
TopSlideNotification.show( // messageController.getMessageList();
context, // messageController.updateAll();
text: apiResponse.msg!, // } else {
textColor: themeController.currentColor.sc2, // TopSlideNotification.show(
); // context,
messageController.getMessageList(); // text: apiResponse.msg!,
messageController.updateAll(); // textColor: themeController.currentColor.sc9,
} else { // );
TopSlideNotification.show( // messageController.getMessageList();
context, // messageController.updateAll();
text: apiResponse.msg!, // }
textColor: themeController.currentColor.sc9, // }, onCancel: () {});
); // }
messageController.getMessageList(); Get.toNamed('/messageDetail', arguments: messageInfo);
messageController.updateAll(); },
} child: Center(
}, onCancel: () {}); child: Text(
} // getMessageStatus(messageInfo['status']),
}, "查看详情",
child: Center( style: TextStyle(
child: Text( fontFamily: 'Inter',
getMessageStatus(messageInfo['status']), fontSize: 26.rpx,
style: TextStyle( letterSpacing: 0.0,
fontFamily: 'Inter', color: Color(0xFF011D33),
fontSize: 26.rpx, ),
letterSpacing: 0.0, ),
color: Colors.white,
), ),
), ),
), ),
), ],
),
), ),
),
], ],
); );
} }

View File

@@ -0,0 +1,319 @@
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/appColors.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/mh_controller/mhdevice_share_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import '../../common/color/appFontsize.dart';
class ShareDeviceDetailWidget extends GetView {
final scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
MHDeviceShareController deviceShareController = Get.find();
var shareInfo = deviceShareController.model.mainShare;
RxInt type = 1.obs;
type.value = shareInfo['op_type'];
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
key: scaffoldKey,
backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtomAddCallback(() {
// controller.saveDataApi();
// updateParm(isShowToast: false);
// }),
// leading: returnIconButtomNew,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'详情',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 0.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1,
decoration: BoxDecoration(
color: Color(0xFFF6F6F6),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 13, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(16, 13, 16, 15),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${shareInfo['userName']}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: 15,
letterSpacing: 0.0,
fontWeight: FontWeight.bold,
),
),
Text(
'分享时间:${MyUtils.timestampToDateString(int.parse(shareInfo['startTime'].toString()))}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 11,
letterSpacing: 0.0,
),
),
].divide(SizedBox(height: 5)),
),
Obx(
() => GestureDetector(
onTap: () {
// 当点击时,将 type 设置为 0允许控制
type.value = 1;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: BoxConstraints(
minHeight: 46,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'允许对方控制该设备'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: 13,
letterSpacing: 0.0,
),
),
Align(
alignment: AlignmentDirectional(0, -1),
child: Icon(
type.value == 1
? Icons.check_circle // 选中时为实心圆
: Icons
.radio_button_unchecked, // 未选中时为空心圆
color: type.value == 1
? Color(0xFFD3B684) // 选中时的颜色
: Colors.grey, // 未选中时的颜色
size: 18,
),
),
],
),
),
),
),
Obx(
() => GestureDetector(
onTap: () {
// 当点击时,将 type 设置为 1仅允许查看
type.value = 2;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: BoxConstraints(
minHeight: 46,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'仅允许对方查看该设备'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: 13,
letterSpacing: 0.0,
),
),
Align(
alignment: AlignmentDirectional(0, -1),
child: Icon(
type.value == 2
? Icons.check_circle // 选中时为实心圆
: Icons
.radio_button_unchecked, // 未选中时为空心圆
color: type.value == 2
? Color(0xFFD3B684) // 选中时的颜色
: Colors.grey, // 未选中时的颜色
size: 18,
),
),
],
),
),
),
),
].divide(SizedBox(height: 13)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
15, 0, 15, AppConstants.page_button_bottom_padding),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.056,
constraints: BoxConstraints(
minHeight: 46,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.056,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: CustomCard(
borderRadius: 16.rpx,
gradientDirection: GradientDirection.vertical,
onTap: () async {},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: double.infinity,
height: 90.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
),
child: Text("解除分享".tr,
style: TextStyle(
color: const Color(0xFF003058),
fontSize: 30.rpx,
)),
),
)
// FFButtonWidget(
// onPressed: () {
// showCustomConfirmDialog(context, "是否确定删除?").then((v) {
// if ('confirm' == v) {
// // deviceShareController
// // .deleteShare(shareInfo)
// // .then((d) {
// // deviceShareController.initData();
// // deviceShareController.updateAll();
// // Get.back();
// // });
// // print("showCustomConfirmDialog $v");
// }
// });
// },
// text: '删除',
// options: FFButtonOptions(
// height: 40,
// padding: EdgeInsetsDirectional.fromSTEB(24, 0, 24, 0),
// iconPadding:
// EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0),
// color: Color(0xFFE55E92),
// textStyle:
// FlutterFlowTheme.of(context).titleSmall.override(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// fontSize: 13,
// letterSpacing: 0.0,
// ),
// elevation: 3,
// borderSide: BorderSide(
// color: Colors.transparent,
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8),
// ),
// ),
),
),
),
],
),
),
),
),
);
}
}

View File

@@ -20,7 +20,7 @@ class ShareUserWidget extends GetView {
onTap: () { onTap: () {
repairListController.model.mainShare = repairListController.model.mainShare =
repairListController.model.shareUser![index]; repairListController.model.shareUser![index];
Get.toNamed('/share_device_user_detail'); Get.toNamed('/shareDeviceDetail');
}, },
child: Container( child: Container(
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,
@@ -77,10 +77,10 @@ class ShareUserWidget extends GetView {
child: Align( child: Align(
alignment: const AlignmentDirectional(-1, 0), alignment: const AlignmentDirectional(-1, 0),
child: Text( child: Text(
info['opType'] == 1 info['op_type'] == 1
? '允许对方控制该设备' ? '允许对方控制该设备'.tr
: info['opType'] == 2 : info['op_type'] == 2
? '仅允许对方查看该设备' ? '仅允许对方查看该设备'.tr
: '', : '',
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',

View File

@@ -0,0 +1,128 @@
import 'package:ef/ef.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/component/tool/WebViewWidget.dart';
class MhAboutUsPage extends StatefulWidget {
late MyWebView webView;
MhAboutUsPage({super.key});
@override
State<MhAboutUsPage> createState() => _MhAboutUsPageState();
}
class _MhAboutUsPageState extends State<MhAboutUsPage> {
@override
void initState() {
super.initState();
// pdfController.loadPdf();
widget.webView = MyWebView(
url: AppConstants().ent_type == 1
? "https://mp.weixin.qq.com/s/BrD3fTT2J2R-DxZrUuM4rw"
: "https://mp.weixin.qq.com/s/7BvvprVDqX1eOzM3Lms8dg",
onLoad: () {
print('网页载入完毕');
},
);
}
@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/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
backgroundColor: Colors.transparent,
// backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text('关于我们'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
)),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
// body: SafeArea(
// top: true,
// child: Padding(
// padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// child: Column(
// children: [
// Expanded(
// child: Obx(() {
// if (pdfController.localPdfPath.value == null) {
// return Center(child: CircularProgressIndicator());
// } else {
// return PDFView(
// filePath: pdfController.localPdfPath.value!,
// autoSpacing: false,
// enableSwipe: true,
// swipeHorizontal: false,
// pageSnap: true,
// fitEachPage: true,
// defaultPage: 0,
// onRender: (pages) => print('PDF 渲染完成,共 $pages 页'),
// onError: (error) => print('PDF 加载错误: $error'),
// );
// }
// }),
// ),
// ],
// ),
// ),
// ),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 0.rpx),
child: Column(children: [
Expanded(
child: Container(
child: widget.webView,
),
),
]),
),
),
),
),
),
);
}
}

View File

@@ -56,7 +56,7 @@ class AddressListPage extends GetView<AddressListController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -71,37 +71,76 @@ class AddressListPage extends GetView<AddressListController> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
// Obx(() {
// if (controller.model.addressList!.isEmpty) {
// // 如果地址列表为空,显示 EmptyMessageWidget
// return Expanded(child: NullDataWidget());
// } else {
// // 如果地址列表不为空,显示地址列表
// return Expanded(
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 1,
// decoration: BoxDecoration(),
// child: Obx(() => ListView(
// shrinkWrap: true,
// scrollDirection: Axis.vertical,
// children: (controller.model.addressList!
// .asMap()
// .entries
// .map((e) => AddressModuleWidget(
// index: e.key,
// addressListController:
// controller,
// ))
// .toList() as List<Widget>)
// .divide(const SizedBox(height: 10))
// .addToEnd(const SizedBox(
// height:
// AppConstants.list_end_height)),
// )),
// ),
// );
// }
// }),
Obx(() { Obx(() {
if (controller.model.addressList!.isEmpty) { final originList = controller.model.addressList ?? [];
// 如果地址列表为空,显示 EmptyMessageWidget
return Expanded(child: NullDataWidget()); // 拆出默认地址
} else { final defaultItem = originList.firstWhere(
// 如果地址列表不为空,显示地址列表 (e) => e["default"] == 1,
return Expanded( orElse: () => null,
child: Container( );
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1, // 其他非默认地址
decoration: BoxDecoration(), final others =
child: Obx(() => ListView( originList.where((e) => e["default"] != 1).toList();
shrinkWrap: true,
scrollDirection: Axis.vertical, // 新的展示顺序列表(默认地址排前面)
children: (controller.model.addressList! final reorderedList = [
.asMap() if (defaultItem != null) defaultItem,
.entries ...others,
.map((e) => AddressModuleWidget( ];
index: e.key,
addressListController: return Expanded(
controller, child: ListView(
)) shrinkWrap: true,
.toList() as List<Widget>) padding: EdgeInsets.zero,
.divide(const SizedBox(height: 10)) children: reorderedList
.addToEnd(const SizedBox( .map((item) {
height: final realIndex =
AppConstants.list_end_height)), originList.indexOf(item); // 保留原始 index
)), return AddressModuleWidget(
), index: realIndex,
); addressListController: controller,
} );
})
.toList()
.divide(const SizedBox(height: 10))
.addToEnd(const SizedBox(
height: AppConstants.list_end_height)),
),
);
}), }),
Align( Align(
alignment: AlignmentDirectional(0, 1), alignment: AlignmentDirectional(0, 1),

View File

@@ -38,7 +38,7 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片 image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container fit: BoxFit.contain, // 填满整个 Container
), ),
), ),
child: Scaffold( child: Scaffold(
@@ -61,11 +61,11 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
Text( Text(
'报修成功标题'.tr, '报修成功标题'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
letterSpacing: 0, letterSpacing: 0,
fontSize: 30.rpx, fontSize: 30.rpx,
), ),
), ),
/// 左边返回按钮 /// 左边返回按钮
@@ -119,7 +119,7 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
// width: double.infinity, // width: double.infinity,
decoration: BoxDecoration(), decoration: BoxDecoration(),
child: SvgPicture.asset('assets/img/icon/tick.svg', child: SvgPicture.asset('assets/img/icon/tick.svg',
fit: BoxFit.cover, color: Color(0XFF84F5FF)), fit: BoxFit.contain, color: Color(0XFF84F5FF)),
), ),
), ),
Padding( Padding(
@@ -132,11 +132,11 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
child: Text( child: Text(
'报修成功'.tr, '报修成功'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: 30.rpx, fontSize: 30.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
), ),
), ),
), ),
@@ -229,12 +229,12 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
Text( Text(
'查看报修历史'.tr, '查看报修历史'.tr,
style: TextStyle( style: TextStyle(
color: Color(0xFF011D33), color: Color(0xFF011D33),
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: AppConstants() fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小 .normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
), ),
].divide(SizedBox(width: 17.rpx)), ].divide(SizedBox(width: 17.rpx)),
), ),
@@ -272,13 +272,13 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
children: [ children: [
Text( Text(
'绑定成功.返回'.tr, '绑定成功.返回'.tr,
style:TextStyle( style: TextStyle(
color: Color(0xFF011D33), color: Color(0xFF011D33),
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: AppConstants() fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小 .normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
), ),
].divide(SizedBox(width: 17.rpx)), ].divide(SizedBox(width: 17.rpx)),
), ),
@@ -322,11 +322,11 @@ class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
Text( Text(
title, title,
style: TextStyle( style: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
color: const Color(0xFFC2CED7), color: const Color(0xFFC2CED7),
fontSize: 30.rpx, fontSize: 30.rpx,
letterSpacing: 0.0, letterSpacing: 0.0,
), ),
), ),
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(8.rpx), borderRadius: BorderRadius.circular(8.rpx),

View File

@@ -79,7 +79,7 @@ class ApplyRepairPage extends GetView<ApplyRepairController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -1168,90 +1168,100 @@ class ApplyRepairPage extends GetView<ApplyRepairController> {
child: child:
TextFormField( TextFormField(
// autofocus: true, // autofocus: true,
obscureText:
false,
onChanged: onChanged:
(value) { (val) {
controller controller
.model .model
.apply_name = .apply_name =
value; val;
}, },
obscureText:
false,
decoration: decoration:
InputDecoration( InputDecoration(
isDense: true, contentPadding:
EdgeInsets
.symmetric(
vertical:
25.rpx,
horizontal:
26.rpx,
),
labelStyle: labelStyle:
const TextStyle( TextStyle(
fontFamily: fontFamily:
'Readex Pro', 'Readex Pro',
letterSpacing: letterSpacing:
0, 0,
), ),
hintStyle: hintStyle:
const TextStyle( TextStyle(
fontFamily: fontFamily:
'Readex Pro', 'Readex Pro',
letterSpacing: letterSpacing:
0, 0,
), ),
enabledBorder: enabledBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
color: const Color( color: Color(
0x00000000), 0x00000000),
width: width: 2,
1.rpx,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
AppConstants().normal_container_radius), .circular(8),
), ),
focusedBorder: focusedBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
color: Colors color: Color(
.transparent, 0x00000000),
width: width: 2,
1.rpx,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
errorBorder: errorBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
// color: Color(
width: 0x00000000),
1.rpx, width: 2,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
focusedErrorBorder: focusedErrorBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
// color: Color(
width: 0x00000000),
1.rpx, width: 2,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
), ),
style: TextStyle( style:
letterSpacing: TextStyle(
0, fontFamily:
color: Colors 'Readex Pro',
.black, letterSpacing:
fontSize: 0,
26.rpx), color: Colors
.black,
fontSize:
26.rpx,
),
), ),
), ),
), ),
@@ -1324,90 +1334,100 @@ class ApplyRepairPage extends GetView<ApplyRepairController> {
child: child:
TextFormField( TextFormField(
// autofocus: true, // autofocus: true,
obscureText:
false,
onChanged: onChanged:
(value) { (val) {
controller controller
.model .model
.tel = .tel =
value; val;
}, },
obscureText:
false,
decoration: decoration:
InputDecoration( InputDecoration(
isDense: true, contentPadding:
EdgeInsets
.symmetric(
vertical:
25.rpx,
horizontal:
26.rpx,
),
labelStyle: labelStyle:
const TextStyle( TextStyle(
fontFamily: fontFamily:
'Readex Pro', 'Readex Pro',
letterSpacing: letterSpacing:
0, 0,
), ),
hintStyle: hintStyle:
const TextStyle( TextStyle(
fontFamily: fontFamily:
'Readex Pro', 'Readex Pro',
letterSpacing: letterSpacing:
0, 0,
), ),
enabledBorder: enabledBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
color: const Color( color: Color(
0x00000000), 0x00000000),
width: width: 2,
1.rpx,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
AppConstants().normal_container_radius), .circular(8),
), ),
focusedBorder: focusedBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
color: Colors color: Color(
.transparent, 0x00000000),
width: width: 2,
1.rpx,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
errorBorder: errorBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
// color: Color(
width: 0x00000000),
1.rpx, width: 2,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
focusedErrorBorder: focusedErrorBorder:
OutlineInputBorder( UnderlineInputBorder(
borderSide: borderSide:
BorderSide( const BorderSide(
// color: Color(
width: 0x00000000),
1.rpx, width: 2,
), ),
borderRadius: borderRadius:
BorderRadius.circular( BorderRadius
8.rpx), .circular(8),
), ),
), ),
style: TextStyle( style:
letterSpacing: TextStyle(
0, fontFamily:
color: Colors 'Readex Pro',
.black, letterSpacing:
fontSize: 0,
26.rpx), color: Colors
.black,
fontSize:
26.rpx,
),
), ),
), ),
), ),

View File

@@ -6,13 +6,28 @@ 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/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/device_list_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class BluetoothPage extends GetView { class BluetoothPage extends StatefulWidget {
Map data; final Map data;
BluetoothPage({required this.data}); BluetoothPage({Key? key, required this.data});
@override
_BluetoothPageState createState() => _BluetoothPageState();
}
class _BluetoothPageState extends State<BluetoothPage> {
late RxMap<String, dynamic> obsData;
@override
void initState() {
super.initState();
obsData = Map<String, dynamic>.from(widget.data).obs; // 复制成 obs
}
BoxConstraints? bodysize; BoxConstraints? bodysize;
DeviceListController deviceListController = Get.find();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) { return LayoutBuilder(builder: (context, cc) {
@@ -50,7 +65,7 @@ class BluetoothPage extends GetView {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -72,7 +87,7 @@ class BluetoothPage extends GetView {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
data['name']?.toString() ?? '未命名', obsData['name']?.toString() ?? '未命名',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 40.rpx, fontSize: 40.rpx,
@@ -83,9 +98,15 @@ class BluetoothPage extends GetView {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
highlightColor: const Color(0xFF055466), highlightColor: const Color(0xFF055466),
padding: EdgeInsets.only(left: 0), padding: EdgeInsets.only(left: 0),
onTap: () { onTap: () async {
Get.toNamed("/editBedPage", var x = await Get.toNamed(
arguments: data); "/editBedPage",
arguments: obsData);
if (x != null) {
setState(() {
obsData.addAll(x); // 值更新后主动刷新页面
});
}
}, },
child: Container( child: Container(
width: 42.rpx, width: 42.rpx,
@@ -98,7 +119,7 @@ class BluetoothPage extends GetView {
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text(data['mac']?.toString() ?? '未命名', Text(obsData['mac']?.toString() ?? '未命名',
style: TextStyle( style: TextStyle(
color: Colors.white70, fontSize: 26.rpx)), color: Colors.white70, fontSize: 26.rpx)),
@@ -107,7 +128,7 @@ class BluetoothPage extends GetView {
// 蓝牙连接状态 // 蓝牙连接状态
Column( Column(
children: [ children: [
data['blueToothStatus'] == 1 obsData['blueToothStatus'] == 1
? SvgPicture.asset( ? SvgPicture.asset(
'assets/img/icon/blue_fail.svg', 'assets/img/icon/blue_fail.svg',
width: 68.rpx, width: 68.rpx,
@@ -121,11 +142,11 @@ class BluetoothPage extends GetView {
SizedBox(height: 4), SizedBox(height: 4),
//下面文字和颜色也根据上面变化 //下面文字和颜色也根据上面变化
Text( Text(
data['blueToothStatus'] == 1 obsData['blueToothStatus'] == 1
? '未连接' ? '未连接'
: '已连接', : '已连接',
style: TextStyle( style: TextStyle(
color: data['blueToothStatus'] == 1 color: obsData['blueToothStatus'] == 1
? Color(0xFFFF7159) ? Color(0xFFFF7159)
: Color(0xFF6BFDAC), : Color(0xFF6BFDAC),
fontSize: 26.rpx)), fontSize: 26.rpx)),
@@ -143,21 +164,74 @@ class BluetoothPage extends GetView {
children: [ children: [
_buildMenuButton( _buildMenuButton(
context, '详情', "/devicePeopleInfo", context, '详情', "/devicePeopleInfo",
arguments: data), arguments: obsData),
_buildMenuButton( _buildMenuButton(
context, '人员资料', "/peopleInfoPage", context, '人员资料', "/peopleInfoPage",
arguments: data), arguments: obsData,),
_buildMenuButton( _buildMenuButton(
context, '房间选择', "/roomPickerPage", context, '房间选择', "/roomPickerPage",
arguments: data), arguments: obsData),
_buildMenuButton(context, '设备校准', ""), _buildMenuButton(context, '设备校准', ""),
_buildMenuButton(context, '体征传感器', ""), _buildMenuButton(context, '体征传感器', ""),
_buildMenuButton(context, 'WIFI配置', ""), _buildMenuButton(context, 'WIFI配置', ""),
_buildMenuButton( _buildMenuButton(
context, '睡眠习惯', "/sleepHabitPage"), context, '睡眠习惯', "/sleepHabitPage"),
_buildMenuButton( _buildMenuButton(
context, '分享设备', "/deviceSharePage"), context, '分享设备', "/deviceSharePage",
_buildMenuButton(context, '解绑', ""), arguments: obsData),
_buildMenuButton(
context,
obsData['bind_type'] == 1 ? '解绑' : '删除',
"",
onTap: () {
if (obsData['bind_type'] == 1) {
// 解绑弹窗
showUnbindConfirmDialog(
context: context,
title: "是否进行解绑?",
onConfirm: () async {
await deviceListController
.unbindDevice(obsData);
await deviceListController
.getDeviceList();
try {
WebviewTestController
webviewTestController =
Get.find();
webviewTestController
.web.jsbridge?.dart
.unBindDevice();
} catch (e) {
ef.log("[h5]通知列表更新报错:$e");
}
Get.toNamed("/mianPageBottomChange");
// 执行解绑逻辑
},
onCancel: () {
// 点击取消后的逻辑
},
);
} else if (obsData['bind_type'] == 2) {
// 删除弹窗
showDeleteDeviceConfirmDialog(
context: context,
title: "是否进行删除?",
onConfirm: () async {
await deviceListController
.unbindDevice(
obsData,
);
await deviceListController
.getDeviceList();
Get.toNamed("/mianPageBottomChange");
},
onCancel: () {
// 点击取消后的逻辑
},
);
}
},
),
], ],
), ),
), ),
@@ -168,8 +242,13 @@ class BluetoothPage extends GetView {
}); });
} }
Widget _buildMenuButton(BuildContext context, String title, String? path, Widget _buildMenuButton(
{Map<dynamic, dynamic>? arguments}) { BuildContext context,
String title,
String? path, {
Map<dynamic, dynamic>? arguments,
VoidCallback? onTap,
}) {
return Padding( return Padding(
padding: EdgeInsets.only(bottom: 19.rpx), padding: EdgeInsets.only(bottom: 19.rpx),
child: ClickableContainer( child: ClickableContainer(
@@ -177,7 +256,21 @@ class BluetoothPage extends GetView {
highlightColor: Color(0XFF055466), highlightColor: Color(0XFF055466),
padding: EdgeInsets.only(left: 0), padding: EdgeInsets.only(left: 0),
onTap: () { onTap: () {
if (path?.isNotEmpty == true) { // if (path?.isNotEmpty == true) {
// if (arguments != null) {
// Get.toNamed(path!, arguments: arguments);
// } else {
// Get.toNamed(path!);
// }
// } else {
// TopSlideNotification.show(
// context,
// text: "功能开发中...",
// );
// }
if (onTap != null) {
onTap(); // 优先执行自定义逻辑
} else if (path?.isNotEmpty == true) {
if (arguments != null) { if (arguments != null) {
Get.toNamed(path!, arguments: arguments); Get.toNamed(path!, arguments: arguments);
} else { } else {

View File

@@ -63,7 +63,7 @@ class BookInfoPage extends GetView<BookInfoController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -62,7 +62,7 @@ class BookSuccessPage extends GetView {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -157,6 +157,8 @@ void showBindDoubleDialog(
); );
} }
Future<void> showUnBindDeviceDialog(BuildContext context) async {}
Future<void> showHaveBindDialog(BuildContext context) async { Future<void> showHaveBindDialog(BuildContext context) async {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();

View File

@@ -49,7 +49,7 @@ class DeletedAccountPage extends GetView {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -20,6 +20,8 @@ import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.dart'; import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.dart';
import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controller.dart'; import 'package:vbvs_app/pages/mh_page/device/controller/mht_bluetooth_controller.dart';
import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart'; import 'package:vbvs_app/pages/mh_page/device/model/BlueToothDataModel.dart';
import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class DeviceComponentWidget extends StatefulWidget { class DeviceComponentWidget extends StatefulWidget {
BlueToothDataModel bleDevice; BlueToothDataModel bleDevice;
@@ -36,6 +38,7 @@ class DeviceComponentWidget extends StatefulWidget {
class _DeviceComponentWidgetState extends State<DeviceComponentWidget> { class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
MHTBlueToothController blueteethBindController = Get.find(); MHTBlueToothController blueteethBindController = Get.find();
MHTHomeController homeController = Get.find();
var lisObj; var lisObj;
@override @override
@@ -172,7 +175,7 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
borderRadius: 16.rpx, borderRadius: 16.rpx,
onTap: () async { onTap: () async {
try { try {
// 连接前暂停扫描 //连接前暂停扫描
blueteethBindController.pauseScanning(); blueteethBindController.pauseScanning();
if (blueteethBindController.currentDeviceMac?.value != if (blueteethBindController.currentDeviceMac?.value !=
null && null &&
@@ -225,6 +228,40 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
TopSlideNotification.show(context, TopSlideNotification.show(context,
text: response.msg!); text: response.msg!);
if (response.code == HttpStatusCodes.ok) { if (response.code == HttpStatusCodes.ok) {
try {
WebviewTestController webviewTestController =
Get.find();
webviewTestController.web.jsbridge?.dart
.unBindDevice();
} catch (e) {
ef.log("[h5]通知列表更新报错:$e");
}
homeController.getPersonList();
//请求绑定设备列表
// homeController.getSleepReport();
homeController.getDeviceNum().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
});
homeController
.getDeviceList(group: 'room')
.then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
} else {
//请求睡眠报告
// deviceController.getSleepReport();
}
});
//更新设备绑定流程 //更新设备绑定流程
Get.toNamed("/mHTwifiPage", Get.toNamed("/mHTwifiPage",
arguments: widget.bleDevice); arguments: widget.bleDevice);
@@ -242,6 +279,7 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
textColor: themeController.currentColor.sc9, textColor: themeController.currentColor.sc9,
); );
} }
blueteethBindController.resumeScanning();
}, },
onCancel: () { onCancel: () {
print('用户点击了取消'); print('用户点击了取消');
@@ -262,10 +300,11 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
DailyLogUtils.writeLog("连接异常: $e"); DailyLogUtils.writeLog("连接异常: $e");
} finally { } finally {
// 确保在任何情况下都恢复扫描 // 确保在任何情况下都恢复扫描
if (blueteethBindController // if (blueteethBindController
.currentDeviceMac.value.isEmpty) { // .currentDeviceMac.value.isEmpty) {
blueteethBindController.resumeScanning(); // blueteethBindController.resumeScanning();
} // }
blueteethBindController.resumeScanning();
} }
}, },
colors: [stringToColor("1592AA"), stringToColor("006FA3")], colors: [stringToColor("1592AA"), stringToColor("006FA3")],
@@ -468,7 +507,7 @@ class _DeviceComponentWidgetState extends State<DeviceComponentWidget> {
blueteethBindController.blueConnectFlag.value = 2; blueteethBindController.blueConnectFlag.value = 2;
blueteethBindController.currentDevice = bledevice; blueteethBindController.currentDevice = bledevice;
await Future.delayed(Duration(seconds: 2));
var read = bledevice.getresource('fff0/fff1'); var read = bledevice.getresource('fff0/fff1');
await read!.characteristic.setNotifyValue(true); await read!.characteristic.setNotifyValue(true);
var write = bledevice.getresource('fff0/fff2'); var write = bledevice.getresource('fff0/fff2');

View File

@@ -25,9 +25,9 @@ class DeviceInfoWidget extends GetView {
child: Container( child: Container(
// width: MediaQuery.sizeOf(context).width, // width: MediaQuery.sizeOf(context).width,
height: 381.rpx, height: 381.rpx,
constraints: BoxConstraints( // constraints: BoxConstraints(
minHeight: 140, // minHeight: 140,
), // ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFF003058), color: Color(0xFF003058),
borderRadius: BorderRadius.circular(16.rpx), borderRadius: BorderRadius.circular(16.rpx),
@@ -37,9 +37,9 @@ class DeviceInfoWidget extends GetView {
child: Container( child: Container(
// width: MediaQuery.sizeOf(context).width, // width: MediaQuery.sizeOf(context).width,
height: 381.rpx, height: 381.rpx,
constraints: BoxConstraints( // constraints: BoxConstraints(
minHeight: 106, // minHeight: 106,
), // ),
child: Container( child: Container(
// width: MediaQuery.sizeOf(context).width, // width: MediaQuery.sizeOf(context).width,
@@ -96,88 +96,99 @@ class DeviceInfoWidget extends GetView {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( _buildInfoRow(
mainAxisSize: MainAxisSize.max, '设备ID',
children: [ deviceListController
Expanded( .model.deviceList[index]["_id"] ??
child: RichText( '',
text: TextSpan( valueColor: (deviceListController
children: [
TextSpan(
text: '设备ID' +
(deviceListController.model
.deviceList[
index]['_id'] ??
''),
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFFC8CBD2),
fontSize: 26.rpx,
letterSpacing: 0,
height: 1),
),
// TextSpan(
// text:
// ' (${deviceListController.model.deviceList[index]['status'] ?? ''})',
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: deviceListController
// .model
// .deviceList[
// index]
// ['status'] ==
// '在线'
// ? Color(
// 0xFF07C160) // 在线的颜色
// : Color(
// 0xFFEA7CA7), // 离线的颜色
// fontSize: 26.rpx,
// letterSpacing: 0,
// ),
// ),
],
),
maxLines: 1, // 限制显示一行
overflow: TextOverflow
.ellipsis, // 超出部分显示省略号
),
),
],
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'房间:' +
(deviceListController
.model.deviceList[index] .model.deviceList[index]
['roomName'] ?? ["status"]?["status"]) ==
''), 1
style: TextStyle( ? Color(0xFF929699)
fontFamily: 'Readex Pro', : null),
color: Color(0xFFC8CBD2), _buildInfoRow(
fontSize: 26.rpx, '房间',
letterSpacing: 0, deviceListController.model
height: 1), .deviceList[index]["roomName"] ??
), '',
), valueColor: (deviceListController
Align( .model.deviceList[index]
alignment: AlignmentDirectional(-1, 0), ["status"]?["status"]) ==
child: Text( 1
'设备状态:' + ? Color(0xFF929699)
(deviceListController : null),
.model _buildInfoRow(
.deviceList[index]["status"] '设备状态',
?["status"] (deviceListController
?.toString() ?? .model.deviceList[index]
''), ["status"]?["status"]) ==
style: TextStyle( 1
fontFamily: 'Readex Pro', ? '在线'
color: Color(0xFFC8CBD2), : '离线',
fontSize: 26.rpx, valueColor: (deviceListController
letterSpacing: 0, .model.deviceList[index]
height: 1), ["status"]?["status"]) ==
), 1
) ? Color(0xFF6BFDAC)
: Color(0xFFFF7159)),
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Expanded(
// child: RichText(
// text: TextSpan(
// children: [
// TextSpan(
// text: '设备ID' +
// (deviceListController.model
// .deviceList[
// index]['_id'] ??
// ''),
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Color(0xFFC8CBD2),
// fontSize: 26.rpx,
// letterSpacing: 0,
// height: 1),
// ),
// ],
// ),
// maxLines: 1, // 限制显示一行
// overflow: TextOverflow
// .ellipsis, // 超出部分显示省略号
// ),
// ),
// ],
// ),
// Align(
// alignment: AlignmentDirectional(-1, 0),
// child: Text(
// '房间:' +
// (deviceListController
// .model.deviceList[index]
// ['roomName'] ??
// ''),
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Color(0xFFC8CBD2),
// fontSize: 26.rpx,
// letterSpacing: 0,
// height: 1),
// ),
// ),
// Align(
// alignment: AlignmentDirectional(-1, 0),
// child: Text(
// '设备状态:${(deviceListController.model.deviceList[index]["status"]?["status"]) == 1 ? '在线' : '离线'}',
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Color(0xFFC8CBD2),
// fontSize: 26.rpx,
// letterSpacing: 0,
// height: 1),
// ),
// )
].divide(SizedBox(height: 36.rpx)), ].divide(SizedBox(height: 36.rpx)),
), ),
), ),
@@ -186,7 +197,7 @@ class DeviceInfoWidget extends GetView {
Align( Align(
alignment: AlignmentDirectional(0, 0), alignment: AlignmentDirectional(0, 0),
child: Container( child: Container(
width: MediaQuery.sizeOf(context).width * 0.21, width: 150.rpx,
height: 90.rpx, height: 90.rpx,
child: FFButtonWidget( child: FFButtonWidget(
onPressed: () { onPressed: () {
@@ -239,7 +250,9 @@ class DeviceInfoWidget extends GetView {
children: [ children: [
InkWell( InkWell(
onTap: () async { onTap: () async {
await Get.toNamed("/deviceSharePage"); await Get.toNamed("/deviceSharePage",
arguments: deviceListController
.model.deviceList[index]);
// if (device['type'] == 1) { // if (device['type'] == 1) {
// globalController.model.deviceMain = device; // globalController.model.deviceMain = device;
// await Get.toNamed("/deviceSharePage"); // await Get.toNamed("/deviceSharePage");
@@ -409,4 +422,25 @@ class DeviceInfoWidget extends GetView {
), ),
); );
} }
Widget _buildInfoRow(String label, String value, {Color? valueColor}) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'$label ',
style:
TextStyle(color: Color(0XFF929699), fontSize: 26.rpx, height: 1),
),
Flexible(
child: Text(
value,
style: TextStyle(
color: valueColor ?? Colors.white, fontSize: 26.rpx, height: 1),
overflow: TextOverflow.ellipsis,
),
),
],
);
}
} }

View File

@@ -601,6 +601,11 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
Obx(() { Obx(() {
if (mhtBlueToothController if (mhtBlueToothController
.model.deviceDataStatus!.isNotEmpty) { .model.deviceDataStatus!.isNotEmpty) {
final sortedList = mhtBlueToothController
.model.deviceDataStatus!
.toList()
..sort((a, b) => b.scanResult.rssi
.compareTo(a.scanResult.rssi));
return Expanded( return Expanded(
child: Container( child: Container(
width: double.infinity, width: double.infinity,
@@ -608,8 +613,7 @@ class _MHTBlueteethDevicePageState extends State<MHTBlueteethDevicePage> {
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
...mhtBlueToothController ...sortedList
.model.deviceDataStatus!
.map((device) { .map((device) {
return DeviceComponentWidget( return DeviceComponentWidget(
bleDevice: device, bleDevice: device,

View File

@@ -8,6 +8,7 @@ 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/ServiceConstant.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart';
@@ -66,10 +67,12 @@ class _MHTWifiPageState extends State<MHTWifiPage> {
blueteethBindController.updateAll(); blueteethBindController.updateAll();
} }
@override
@override @override
void dispose() { void dispose() {
_isDisposed = true; _isDisposed = true;
_cleanupResources(); _cleanupResources();
_disconnectDevice();
super.dispose(); super.dispose();
} }
@@ -1097,4 +1100,14 @@ class _MHTWifiPageState extends State<MHTWifiPage> {
onFailure: (res) {}, onFailure: (res) {},
); );
} }
void _disconnectDevice() async {
try {
THapp bledevice = THapp(device: widget.deviceInfo.scanResult.device);
await bledevice.disconnect();
DailyLogUtils.writeLog("关闭蓝牙连接成功");
} catch (e) {
DailyLogUtils.writeError("关闭蓝牙连接失败: $e");
}
}
} }

View File

@@ -70,7 +70,7 @@ class _DeviceListPageState extends State<DeviceListPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -74,7 +74,7 @@ class DevicePeopleInfo extends GetView<PeopleInfoController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -146,13 +146,13 @@ class DevicePeopleInfo extends GetView<PeopleInfoController> {
...List.generate(controller.model.peopleList.length, ...List.generate(controller.model.peopleList.length,
(index) { (index) {
final person = controller.model.peopleList[index]; final person = controller.model.peopleList[index];
String location_ = ''; // String location_ = '';
if ("${data["bindMacB"]}".length > 6 && // if ("${data["bindMacB"]}".length > 6 &&
(person["direction"] == 1 || // (person["direction"] == 1 ||
person["direction"] == 2)) { // person["direction"] == 2)) {
location_ = // location_ =
person["direction"] == 1 ? '左侧' : '右侧'; // person["direction"] == 1 ? '左侧' : '右侧';
} // }
return ClickableContainer( return ClickableContainer(
backgroundColor: Color(0xFF003058), backgroundColor: Color(0xFF003058),
@@ -176,9 +176,8 @@ class DevicePeopleInfo extends GetView<PeopleInfoController> {
), ),
), ),
), ),
if (location_.isNotEmpty) getInfoRow(
getInfoRow(context, context, "姓名:${person["name"] ?? "-"}"),
"姓名:${person["name"] ?? "-"}"),
getInfoRow(context, getInfoRow(context,
"性别:${person["gender"] == null ? "-" : (person["gender"] == 1 ? "" : "")}"), "性别:${person["gender"] == null ? "-" : (person["gender"] == 1 ? "" : "")}"),
getInfoRow(context, getInfoRow(context,

View File

@@ -3,40 +3,31 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.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/CommonVariables.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/mhdevice_share_controller.dart'; import 'package:vbvs_app/controller/mh_controller/mhdevice_share_controller.dart';
import 'package:vbvs_app/pages/mh_page/EmptyMessageWidget.dart'; import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/mh_page/ShareUserWidget.dart'; import 'package:vbvs_app/pages/mh_page/ShareUserWidget.dart';
class ShareDeviceWidget extends GetView<MHDeviceShareController> { class ShareDeviceWidget extends GetView<MHDeviceShareController> {
var data;
ShareDeviceWidget({super.key, required this.data});
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
// ShareDeviceWidget() {
// controller.initData();
// scrollController.addListener(() {
// if (scrollController.position.pixels ==
// scrollController.position.maxScrollExtent &&
// controller.model.hasMore) {
// controller.initData();
// controller.updateAll();
// }
// });
// }
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final _phoneController = TextEditingController(); final _phoneController = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var deviceController = Get.find<GlobalController>();
controller.model.msg = ""; controller.model.msg = "";
controller.model.show = 0; controller.model.code = 0;
controller.model.type = 1; controller.model.type = 1;
controller.model.account = '';
return GestureDetector( return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
child: Container( child: Container(
@@ -69,7 +60,7 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -122,7 +113,7 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
), ),
), ),
Text( Text(
'设备ID${deviceController.model.deviceMain['mac']}', '设备ID${data['mac']}',
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: const Color(0xFF6BFDAC), color: const Color(0xFF6BFDAC),
@@ -152,7 +143,7 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
child: TextFormField( child: TextFormField(
controller: _phoneController, controller: _phoneController,
decoration: InputDecoration( decoration: InputDecoration(
hintText: '请输入对方手机号', hintText: '请输入对方手机号/邮箱号',
hintStyle: TextStyle( hintStyle: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: color:
@@ -192,82 +183,12 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
color: Colors.white, color: Colors.white,
fontSize: 36.rpx, fontSize: 36.rpx,
), ),
validator: (value) {
if (value == null ||
value.isEmpty) {
return '手机号不能为空';
}
final phoneReg =
RegExp(r'^1[3-9]\d{9}$');
if (!phoneReg.hasMatch(value)) {
return '请输入正确的手机号';
}
return null;
},
onChanged: (value) { onChanged: (value) {
controller.model.phone = value; controller.model.account =
value;
}, },
), ),
) )),
// TextFormField(
// // controller: _model.textController,
// // focusNode: _model.textFieldFocusNode,
// // autofocus: true,
// obscureText: false,
// decoration: InputDecoration(
// hintText: '请输入对方手机号',
// hintStyle: FlutterFlowTheme.of(
// context)
// .labelMedium
// .override(
// fontFamily: 'Readex Pro',
// color:
// const Color(0xFFD2D2D2),
// fontSize: 13,
// letterSpacing: 0.0,
// ),
// enabledBorder:
// const UnderlineInputBorder(
// borderSide: BorderSide(
// color: Color(0xFFCCCCCC),
// width: 1),
// ),
// focusedBorder:
// const UnderlineInputBorder(
// borderSide: BorderSide(
// color: Color(0xFF929699),
// width: 0),
// ),
// errorBorder:
// const UnderlineInputBorder(
// borderSide: BorderSide(
// color: Colors.red, width: 1),
// ),
// focusedErrorBorder:
// const UnderlineInputBorder(
// borderSide: BorderSide(
// color: Colors.redAccent,
// width: 1.5),
// ),
// contentPadding:
// const EdgeInsets.only(
// left: 10, bottom: 5),
// ),
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// fontSize: 13,
// letterSpacing: 0.0,
// ),
// onChanged: (value) {
// controller.model.phone = value;
// },
// // validator: _model.textControllerValidator
// // .asValidator(context),
// ),
),
), ),
), ),
ClickableContainer( ClickableContainer(
@@ -292,236 +213,280 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
), ),
), ),
)), )),
// Container( GestureDetector(
// width: MediaQuery.sizeOf(context).width, onTap: () {
// constraints: const BoxConstraints( // 当点击时,将 type 设置为 0允许控制
// minHeight: 46, controller.model.type = 1;
// ), controller.updateAll();
// decoration: BoxDecoration( },
// borderRadius: BorderRadius.circular(0), child: Container(
// ), margin: EdgeInsets.only(top: 76.rpx),
// child: Align( width: MediaQuery.sizeOf(context).width,
// alignment: constraints: const BoxConstraints(
// const AlignmentDirectional(0, 0), minHeight: 46,
// child: Obx(() { ),
// if (controller.model.show == 0) { decoration: BoxDecoration(
// return Container(); borderRadius: BorderRadius.circular(0),
// } else { ),
// return GestureDetector( child: Row(
// onTap: controller mainAxisSize: MainAxisSize.max,
// .model.msg!.isNotEmpty mainAxisAlignment:
// ? () { MainAxisAlignment.spaceBetween,
// Clipboard.setData( children: [
// ClipboardData( Text(
// text: CommonVariables '允许对方控制该设备'.tr,
// .shareText)); style: TextStyle(
// showToast( fontFamily: 'Readex Pro',
// "复制成功粘贴分享APP下载链接", color: Colors.white,
// color: color_success); fontSize: 26.rpx,
// } letterSpacing: 0.0,
// : null, // 不可点击时设置为 null ),
// child: RichText( ),
// textAlign: TextAlign Obx(() {
// .center, // 设置整个 RichText 内容居中 double h = 33.rpx;
// text: TextSpan( bool check =
// children: controller.model.type == 1;
// controller.model.msg!
// .isNotEmpty return Container(
// ? [ height: 33.rpx,
// TextSpan( child: AspectRatio(
// text: controller aspectRatio: 1,
// .model child: Center(
// .msg! + child: Container(
// "!", // 第一部分文本 height: h,
// style: FlutterFlowTheme.of( width: h,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(
h / 2),
border: Border.all(
width: check ? 1 : 0.5,
color:
Color(0xFFC8CBD2),
),
),
child: check
? Center(
child: ClipOval(
child: Container(
width: h * 0.6,
height: h * 0.6,
color: const Color(
0xFF6BFDAC),
),
),
)
: null,
),
),
),
);
}),
],
),
),
),
// Obx(
// () => GestureDetector(
// onTap: () {
// controller.model.type = 2;
// controller.updateAll();
// },
// child: Container(
// width: MediaQuery.sizeOf(context).width,
// constraints: const BoxConstraints(
// minHeight: 46,
// ),
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(0),
// ),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '仅允许对方查看该设备'.tr,
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// // Theme(
// // data:
// // Theme.of(context).copyWith(
// // unselectedWidgetColor: Color(
// // 0xFFC8CBD2), // 改变未选中状态边框颜色
// // ),
// // child: Radio<int>(
// // value: 2,
// // groupValue:
// // controller.model.type,
// // onChanged: (value) {
// // controller.model.type =
// // value!;
// // controller.updateAll();
// // },
// // activeColor:
// // const Color(0xFF6BFDAC),
// // materialTapTargetSize:
// // MaterialTapTargetSize
// // .shrinkWrap, // 减少内边距
// // visualDensity: VisualDensity(
// // horizontal: -4,
// // vertical: -4), // 缩小视觉密度
// // ))
// ClipOval(
// child: Container(
// height:
// MediaQuery.sizeOf(context)
// .height *
// 0.0449,
// child: AspectRatio(
// aspectRatio: 1,
// child: Center(
// child: LayoutBuilder(
// builder: (context,
// constraints) {
// double h =
// MediaQuery.sizeOf(
// context) // context)
// .bodyMedium // .height *
// .override( // 0.0326;
// fontFamily: // bool check = controller
// 'Readex Pro', // .model.type ==
// color: const Color( // 2;
// 0xFFE55E92), // 设置为粉红色 // if (check) {
// fontSize: // return Container(
// 26.rpx, // height: h,
// letterSpacing: // width: h,
// 0.0, // decoration:
// ), // BoxDecoration(
// borderRadius:
// BorderRadius
// .circular(
// h / 2),
// border: Border.all(
// width: 1,
// color: Color(
// 0xFF6BFDAC)),
// ),
// child: Center(
// child: ClipOval(
// child: Container(
// width:
// h * 0.6,
// height:
// h * 0.6,
// color: Color(
// 0xFF6BFDAC)),
// ), // ),
// const TextSpan( // ),
// text: // );
// '\n', // 添加换行 // } else {
// ), // return Container(
// WidgetSpan( // height: h,
// child: SizedBox( // width: h,
// height: 20 // decoration:
// .rpx), // 添加间距 // BoxDecoration(
// ), // borderRadius:
// TextSpan( // BorderRadius
// text: // .circular(
// '点击复制APP下载链接', // 第二部分文本 // h / 2),
// style: FlutterFlowTheme.of( // border: Border.all(
// context) // width: 0.5,
// .bodyMedium // color: Colors
// .override( // .white),
// fontFamily: // ),
// 'Readex Pro', // );
// color: const Color( // }
// 0xFF1890FF), // 设置为蓝色 // },
// fontSize: // ),
// 20.rpx, // ),
// letterSpacing:
// 0.0,
// decoration:
// TextDecoration
// .underline, // 添加下划线
// ),
// ),
// ]
// : [
// TextSpan(
// text:
// '发送成功!', // 当 msg 为空时显示的文本
// style: FlutterFlowTheme.of(
// context)
// .bodyMedium
// .override(
// fontFamily:
// 'Readex Pro',
// color: const Color(
// 0xFF07C160), // 设置为绿色
// fontSize:
// 20.rpx,
// letterSpacing:
// 0.0,
// ),
// ),
// ],
// ), // ),
// ), // ),
// ); // ),
// } // ],
// })), // ),
// ),
// ),
// ), // ),
GestureDetector(
onTap: () {
controller.model.type = 2;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints:
const BoxConstraints(minHeight: 46),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'仅允许对方查看该设备'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
// ✅ 只包住响应式控件部分
Obx(() {
double h = 33.rpx;
bool check =
controller.model.type == 2;
Obx( return Container(
() => GestureDetector( height: 33.rpx,
onTap: () { child: AspectRatio(
// 当点击时,将 type 设置为 0允许控制 aspectRatio: 1,
controller.model.type = 1; child: Center(
controller.updateAll(); child: Container(
}, height: h,
child: Container( width: h,
margin: EdgeInsets.only(top: 76.rpx), decoration: BoxDecoration(
width: MediaQuery.sizeOf(context).width, borderRadius:
constraints: const BoxConstraints( BorderRadius.circular(
minHeight: 46, h / 2),
), border: Border.all(
decoration: BoxDecoration( width: check ? 1 : 0.5,
borderRadius: color:
BorderRadius.circular(0), Color(0xFFC8CBD2),
), ),
child: Row( ),
mainAxisSize: MainAxisSize.max, child: check
mainAxisAlignment: ? Center(
MainAxisAlignment.spaceBetween, child: ClipOval(
children: [ child: Container(
Text( width: h * 0.6,
'允许对方控制该设备', height: h * 0.6,
style: TextStyle( color: const Color(
fontFamily: 'Readex Pro', 0xFF6BFDAC),
color: Colors.white, ),
fontSize: 26.rpx, ),
letterSpacing: 0.0, )
), : null,
), ),
Theme(
data:
Theme.of(context).copyWith(
unselectedWidgetColor: Color(
0xFFC8CBD2), // 改变未选中状态边框颜色
), ),
child: Radio<int>( ),
value: 1, );
groupValue: }),
controller.model.type, ],
onChanged: (value) {
controller.model.type =
value!;
controller.updateAll();
},
activeColor:
const Color(0xFF6BFDAC),
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap, // 减少内边距
visualDensity: VisualDensity(
horizontal: -4,
vertical: -4), // 缩小视觉密度
))
],
),
),
),
),
Obx(
() => GestureDetector(
onTap: () {
// 当点击时,将 type 设置为 1仅允许查看
controller.model.type = 2;
controller.updateAll();
},
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: const BoxConstraints(
minHeight: 46,
),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'仅允许对方查看该设备',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0.0,
),
),
Theme(
data:
Theme.of(context).copyWith(
unselectedWidgetColor: Color(
0xFFC8CBD2), // 改变未选中状态边框颜色
),
child: Radio<int>(
value: 2,
groupValue:
controller.model.type,
onChanged: (value) {
controller.model.type =
value!;
controller.updateAll();
},
activeColor:
const Color(0xFF6BFDAC),
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap, // 减少内边距
visualDensity: VisualDensity(
horizontal: -4,
vertical: -4), // 缩小视觉密度
))
],
),
), ),
), ),
), ),
Align( Align(
alignment: const AlignmentDirectional(0, 0), alignment: const AlignmentDirectional(0, 0),
child: Padding( child: Padding(
@@ -534,18 +499,21 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
child: FFButtonWidget( child: FFButtonWidget(
onPressed: () async { onPressed: () async {
//todo 1:验证用户是否存在 2发送邀请 //todo 1:验证用户是否存在 2发送邀请
// controller.model.show = 1; ApiResponse apiResponse =
// String msg = await controller
// await controller.sendInvite( .shareDevice(data['mac']);
// controller.model.phone, if (apiResponse.code ==
// deviceController HttpStatusCodes.ok) {
// .model.deviceMain['mac']); TopSlideNotification.show(context,
// if (msg != null && msg.isNotEmpty) { text: apiResponse.msg!);
// controller.model.msg = msg; } else {
// } TopSlideNotification.show(context,
// controller.updateAll(); text: apiResponse.msg!,
textColor: themeController
.currentColor.sc9);
}
}, },
text: '发送邀请', text: '发送邀请'.tr,
options: FFButtonOptions( options: FFButtonOptions(
height: 60.rpx, height: 60.rpx,
padding: padding:
@@ -588,7 +556,7 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
padding: const EdgeInsetsDirectional padding: const EdgeInsetsDirectional
.fromSTEB(14, 0, 0, 16), .fromSTEB(14, 0, 0, 16),
child: Text( child: Text(
'已分享用户', '已分享用户'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Colors.white, color: Colors.white,
@@ -617,10 +585,11 @@ class ShareDeviceWidget extends GetView<MHDeviceShareController> {
// .bodyMedium, // 可根据需要自定义样式 // .bodyMedium, // 可根据需要自定义样式
// ), // ),
// ); // );
return EmptyMessageWidget( return NullDataWidget();
imagePath: // EmptyMessageWidget(
"assets/images/emptyUser.png", // imagePath:
); // "assets/images/emptyUser.png",
// );
} }
// 否则显示正常的 ListView // 否则显示正常的 ListView

View File

@@ -2,6 +2,7 @@ import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_city_picker/listener/picker_listener.dart'; import 'package:flutter_city_picker/listener/picker_listener.dart';
import 'package:flutter_city_picker/model/address.dart'; import 'package:flutter_city_picker/model/address.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';
@@ -79,7 +80,7 @@ class EditAddressPage extends GetView<AddressController>
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -739,6 +740,158 @@ class EditAddressPage extends GetView<AddressController>
], ],
), ),
), ),
// Expanded(
// child: InkWell(
// onTap: () {
// CityPicker.show(
// context:
// context,
// cityPickerListener:
// this,
// // 在大屏/Web 上最大宽度为 600px
// // 移除内边距
// );
// },
// child: Container(
// width: 100,
// height: 100,
// decoration:
// BoxDecoration(
// color: const Color(
// 0xFFF3F5F6),
// borderRadius:
// BorderRadius
// .circular(
// 8),
// ),
// alignment:
// Alignment
// .center,
// child: Obx(() {
// return TextFormField(
// enabled:
// false,
// controller: controller.onReDraw(
// TextEditingController(
// text:
// controller.model.all_address),
// (val) {
// val.text =
// controller.model.all_address ??
// "";
// }),
// // autofocus: true,
// obscureText:
// false,
// maxLines: 1,
// textAlignVertical:
// TextAlignVertical
// .center, // 垂直居中
// decoration: InputDecoration(
// contentPadding: EdgeInsets.symmetric(
// vertical:
// 25.rpx,
// horizontal:
// 26.rpx,
// ),
// labelStyle: TextStyle(
// fontFamily:
// 'Readex Pro',
// letterSpacing:
// 0,
// ),
// hintStyle: TextStyle(
// fontFamily:
// 'Readex Pro',
// letterSpacing:
// 0,
// ),
// enabledBorder: UnderlineInputBorder(
// borderSide:
// const BorderSide(
// color:
// Color(0x00000000),
// width:
// 2,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// disabledBorder: UnderlineInputBorder(
// borderSide:
// const BorderSide(
// color:
// Color(0x00000000),
// width:
// 0,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// focusedBorder: UnderlineInputBorder(
// borderSide:
// const BorderSide(
// color:
// Color(0x00000000),
// width:
// 2,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// errorBorder: UnderlineInputBorder(
// borderSide:
// const BorderSide(
// color:
// Color(0x00000000),
// width:
// 2,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// focusedErrorBorder: UnderlineInputBorder(
// borderSide:
// const BorderSide(
// color:
// Color(0x00000000),
// width:
// 2,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// suffixIcon: Transform.rotate(
// angle:
// 1.5708, // 90 度相当于 pi / 2 弧度
// child:
// Icon(
// Icons.arrow_forward_ios,
// color:
// Colors.black,
// size:
// 26.rpx,
// ),
// )),
// style:
// TextStyle(
// fontFamily:
// 'Readex Pro',
// letterSpacing:
// 0,
// color: Color(
// 0xFF333333),
// fontSize:
// 26.rpx,
// overflow:
// TextOverflow
// .ellipsis,
// ),
// );
// })),
// ),
// ),
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: () { onTap: () {
@@ -747,148 +900,71 @@ class EditAddressPage extends GetView<AddressController>
context, context,
cityPickerListener: cityPickerListener:
this, this,
// 在大屏/Web 上最大宽度为 600px
// 移除内边距
); );
}, },
child: Container( child: Container(
width: 100, width: 100,
height: 100, height: 100,
decoration: decoration:
BoxDecoration( BoxDecoration(
color: const Color( color: const Color(
0xFFF3F5F6), 0xFFF3F5F6),
borderRadius: borderRadius:
BorderRadius BorderRadius
.circular( .circular(
8), 8),
), ),
alignment: alignment:
Alignment Alignment
.center, .center,
child: Obx(() { child: Obx(() {
return TextFormField( return Row(
enabled: children: [
false, Expanded(
controller: controller.onReDraw( child:
TextEditingController( Padding(
text: padding: EdgeInsets.only(
controller.model.all_address), left: 27
(val) { .rpx,
val.text = right:
controller.model.all_address ?? 10.rpx),
""; child:
}), Text(
// autofocus: true, controller.model.all_address ??
obscureText: '',
false, maxLines:
textAlignVertical: 1,
TextAlignVertical overflow:
.center, // 垂直居中 TextOverflow.ellipsis,
decoration: InputDecoration( style:
contentPadding: EdgeInsets.symmetric( TextStyle(
vertical: fontFamily:
25.rpx, 'Readex Pro',
horizontal: letterSpacing:
0,
color:
Color(0xFF333333),
fontSize:
26.rpx, 26.rpx,
), ),
labelStyle: TextStyle( ),
fontFamily: )),
'Readex Pro', Padding(
letterSpacing: padding:
0, EdgeInsets.only(right: 27.rpx),
), child: Container(
hintStyle: TextStyle( height: 30.rpx,
fontFamily: width: 30.rpx,
'Readex Pro', child: SvgPicture.asset(
letterSpacing: 'assets/img/icon/expand_more.svg',
0, color: Colors.black,
), )))
enabledBorder: UnderlineInputBorder( ],
borderSide: );
const BorderSide( }),
color: ),
Color(0x00000000),
width:
2,
),
borderRadius:
BorderRadius.circular(8),
),
disabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width:
0,
),
borderRadius:
BorderRadius.circular(8),
),
focusedBorder: UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width:
2,
),
borderRadius:
BorderRadius.circular(8),
),
errorBorder: UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width:
2,
),
borderRadius:
BorderRadius.circular(8),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width:
2,
),
borderRadius:
BorderRadius.circular(8),
),
suffixIcon: Transform.rotate(
angle:
1.5708, // 90 度相当于 pi / 2 弧度
child:
Icon(
Icons.arrow_forward_ios,
color:
Colors.black,
size:
26.rpx,
),
)),
style:
TextStyle(
fontFamily:
'Readex Pro',
letterSpacing:
0,
color: Color(
0xFF333333),
fontSize:
26.rpx,
overflow:
TextOverflow
.ellipsis,
),
);
})),
), ),
), )
].divide(const SizedBox( ].divide(const SizedBox(
width: 15)), width: 15)),
), ),

View File

@@ -6,6 +6,9 @@ import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/device_list_controller.dart';
import 'package:vbvs_app/pages/mh_page/bluetooth.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class EditBedPage extends StatefulWidget { class EditBedPage extends StatefulWidget {
final Map data; final Map data;
@@ -19,6 +22,7 @@ BoxConstraints? bodysize;
class _EditBedPageState extends State<EditBedPage> { class _EditBedPageState extends State<EditBedPage> {
late Map<String, dynamic> editedData; late Map<String, dynamic> editedData;
late TextEditingController _nameController; //名称文本输入框 late TextEditingController _nameController; //名称文本输入框
DeviceListController deviceListController = Get.find();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -71,7 +75,7 @@ class _EditBedPageState extends State<EditBedPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -117,7 +121,7 @@ class _EditBedPageState extends State<EditBedPage> {
editedData['name'] = val; editedData['name'] = val;
}, },
textAlign: TextAlign.center, textAlign: TextAlign.center,
initialValue: widget.data['name'],
decoration: InputDecoration( decoration: InputDecoration(
hintText: "请输入床的名称", hintText: "请输入床的名称",
contentPadding: contentPadding:
@@ -205,6 +209,16 @@ class _EditBedPageState extends State<EditBedPage> {
onSuccess: (res) { onSuccess: (res) {
TopSlideNotification.show(context, TopSlideNotification.show(context,
text: "修改名称成功".tr); text: "修改名称成功".tr);
deviceListController.getDeviceList();
try {
WebviewTestController
webviewTestController = Get.find();
webviewTestController.web.jsbridge?.dart
.alterDevice();
} catch (e) {
ef.log("[h5]通知列表更新错误:$e");
}
Get.back(result: editedData);
}, },
); );
}, },
@@ -222,7 +236,7 @@ class _EditBedPageState extends State<EditBedPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
), ),
child: Text("完成", child: Text("完成".tr,
style: TextStyle( style: TextStyle(
color: const Color(0xFF003058), color: const Color(0xFF003058),
fontSize: 26.rpx)), fontSize: 26.rpx)),

View File

@@ -11,6 +11,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/NullDataComponentWidget.dart'; import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/experience_store_list_page.dart'; import 'package:vbvs_app/controller/mh_controller/experience_store_list_page.dart';
import 'package:vbvs_app/controller/weather/weather_controller.dart'; import 'package:vbvs_app/controller/weather/weather_controller.dart';
import 'package:vbvs_app/pages/mh_page/Empty.dart'; import 'package:vbvs_app/pages/mh_page/Empty.dart';
@@ -94,7 +95,7 @@ class _ExperienceStorePageState extends State<ExperienceStorePage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
Positioned( Positioned(
@@ -104,7 +105,9 @@ class _ExperienceStorePageState extends State<ExperienceStorePage> {
highlightColor: Color(0xFF055466), highlightColor: Color(0xFF055466),
padding: EdgeInsets.only(left: 0), padding: EdgeInsets.only(left: 0),
onTap: () { onTap: () {
Get.toNamed("/myExperiencePage"); TopSlideNotification.show(context,
text: "待开发功能".tr);
// Get.toNamed("/myExperiencePage");
}, },
child: SvgPicture.asset( child: SvgPicture.asset(
'assets/img/icon/history_store.svg', 'assets/img/icon/history_store.svg',

View File

@@ -2,135 +2,147 @@ import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:vbvs_app/common/color/appColors.dart'; import 'package:vbvs_app/common/color/appColors.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/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
class HelpArticle extends StatelessWidget { class HelpArticle extends StatefulWidget {
Map article; final Map article;
HelpArticle({super.key, required this.article}); HelpArticle({super.key, required this.article});
// get articleController => Get.find<ArticleController>(); @override
get userInfoController => Get.find<UserInfoController>(); State<HelpArticle> createState() => _HelpArticleState();
}
var isLike = 0.obs; class _HelpArticleState extends State<HelpArticle> {
bool isLoading = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String top_imgOrVideo = ""; return Container(
if (article['imgOrVideo'] == 0) { decoration: const BoxDecoration(
top_imgOrVideo = image: DecorationImage(
'''<img class="video" src="${getStorageResourceUrl(article['coverUrl'])}" />'''; image: AssetImage('assets/images/new_background.png'), // 本地图片
} else { fit: BoxFit.fill, // 填满整个 Container
top_imgOrVideo =
'''<video controls class="video" src="${getStorageResourceUrl(article['videoUrl'])}" ></video>''';
}
String newText = article['text'];
RegExp("<img\\s*src=\"([^\"]*)\"")
.allMatches(newText)
.toList()
.map((d) => d.group(1))
.toList()
.forEach((d) {
newText = newText.replaceAll("$d", getStorageResourceUrl("$d"));
});
String html = '''
<html>
<meta name="viewport" charset="UTF-8"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<head>
<title>Test Page</title>
</head>
<style>
body {
width: 98%;
margin: 0 auto;
overflow-x: hidden;
}
.video {
width: 100%;
height: 270px;
background-color: #9EA4B7;
border-radius: 6px;
}
</style>
<body>
<div style="padding: 15px;width: calc(100% - 36px);">
${top_imgOrVideo}
<div style="height: 2px;width: 100%;background-color: #D6D6D6;margin: 15px 0 15px 0;"></div>
<div style="line-height: 22px;font-size: 15px;">${article['title']}</div>
<div style="display: flex;align-items: center;font-size: 13;margin-bottom: 24px;margin-top: 10px;">
<div style="color: #182B7C;">${article['author']}</div>
<div style="margin-left: 13px; color: #D3D3D3;">${time_08_Formatter(article['created_at'])}</div>
</div>
${newText}
</div>
</body>
</html>
''';
print("$html");
// articleController.readAdd(article['id']);
String? uid = userInfoController.model.user?.uid;
print("${userInfoController.model.user}");
// uid = "sss";
// if (uid != null) {
// articleController.findIsLike(uid, article['id']).then((d) {
// isLike.value = d;
// });
// }
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
appBar: AppBar(
backgroundColor: AppColors.bg_color,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
leading: returnIconButtom,
), ),
body: SafeArea( ),
top: true, child: Scaffold(
child: Container( backgroundColor: Colors.transparent,
width: MediaQuery.sizeOf(context).width, appBar: AppBar(
height: MediaQuery.sizeOf(context).height, backgroundColor: Colors.transparent,
decoration: BoxDecoration( automaticallyImplyLeading: false,
color: Colors.white, iconTheme: IconThemeData(color: Colors.white),
// color: AppColors.bg_color, titleSpacing: 0,
// image: DecorationImage( title: SizedBox(
// image: AssetImage("assets/images/background.png$test"), width: double.infinity,
// fit: BoxFit.cover, height: 180.rpx,
// ), child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'问题与帮助',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 0.rpx,
child: returnIconButtomNew,
),
],
),
), ),
actions: [],
centerTitle: false,
),
body: Padding(
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Column( child: Column(
children: [ children: [
Expanded( Container(
child: Container( padding: EdgeInsets.only(
// child: WebViewWidget( left: 26.rpx, top: 53.rpx, bottom: 15.rpx),
// controller: WebViewController() alignment: Alignment.centerLeft,
// ..setJavaScriptMode(JavaScriptMode.unrestricted) child: Text(
// ..loadHtmlString(html), widget.article['title'],
// ), style: TextStyle(
child: InAppWebView( color: Colors.white,
initialData: fontSize: 30.rpx,
InAppWebViewInitialData(data: html, encoding: ""),
), ),
), ),
), ),
Divider(
color: Color(0XFF929699),
thickness: 0.5.rpx,
),
Expanded(
child: Stack(
children: [
InAppWebView(
initialData: InAppWebViewInitialData(
data: wrapHtml(widget.article['content']),
),
initialSettings: InAppWebViewSettings(
transparentBackground: true,
),
onLoadStop: (controller, url) {
setState(() {
isLoading = false;
});
},
),
if (isLoading)
Container(
color: const Color(0xFF042C46),
alignment: Alignment.center,
child: const CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(Colors.white),
),
),
],
),
),
], ],
), ),
), )));
), }
),
), String wrapHtml(String htmlContent) {
); return """
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
color: #929699;
background-color: transparent;
font-family: sans-serif;
padding: 0;
font-size: 18;
}
p, li {
line-height: 1.6;
}
ol {
padding-left: 20px;
}
strong {
color: #6BFDAC;
}
</style>
</head>
<body>
$htmlContent
</body>
</html>
""";
} }
} }

View File

@@ -2,9 +2,12 @@ import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class HomeDeviceStausWidget extends StatefulWidget { class HomeDeviceStausWidget extends StatefulWidget {
final deviceStatus; final deviceStatus;
@@ -72,9 +75,22 @@ class _HomeDeviceStausWidgetState extends State<HomeDeviceStausWidget> {
CustomCard( CustomCard(
gradientDirection: GradientDirection.vertical, gradientDirection: GradientDirection.vertical,
borderRadius: 10.rpx, borderRadius: 10.rpx,
onTap: () { onTap: () async {
// 点击回调逻辑放这里 try {
TopSlideNotification.show(context,text: "功能开发中...".tr); var device = widget.deviceStatus;
WebviewTestController webviewTestController = Get.find();
var future = webviewTestController.web.jsbridge?.dart
.appToHtmlDevice(device);
Future.delayed(Duration(seconds: 5), () {
return;
});
await future;
await webviewTestController.web.jsbridge?.dart
.pageActive();
MainPageBBottomChange.jumpTo(2);
} catch (e) {
DailyLogUtils.writeError("发生异常: $e");
}
}, },
colors: colors:
AppConstants().mhtButtongradientColors, // 你原本没有渐变,单色即可 AppConstants().mhtButtongradientColors, // 你原本没有渐变,单色即可

View File

@@ -39,6 +39,7 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
RxInt bindDeviceNum = 0.obs; //设备数量 RxInt bindDeviceNum = 0.obs; //设备数量
RxMap deviceList = {}.obs; //设备列表 RxMap deviceList = {}.obs; //设备列表
RxList deviceListForWeb = [].obs; //h5设备列表
RxMap<String, List<dynamic>> sleepReportData = RxMap<String, List<dynamic>> sleepReportData =
<String, List<dynamic>>{}.obs; //睡眠报告 <String, List<dynamic>>{}.obs; //睡眠报告
RxList personnelList = [].obs; //人员信息列表 RxList personnelList = [].obs; //人员信息列表
@@ -49,12 +50,13 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
var sleepDays = [].obs; var sleepDays = [].obs;
var homeSleepDays = [].obs; var homeSleepDays = [].obs;
var selectedDayIndex = (6).obs; var selectedDayIndex = (6).obs;
var selectDevcie = ''.obs; var selectDevcie = ''.obs;
var selectPerson = {}.obs; var selectPerson = {}.obs;
bool initDeviceFlag = false;
Future<ApiResponse> getDeviceNum() async { Future<ApiResponse> getDeviceNum() async {
try { try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr); ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr);
@@ -159,6 +161,68 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
} }
Future<ApiResponse> getDeviceListForWeb(
{String? key, String? group, int? bindType}) async {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_list;
// 初始URL
String queryUrl = "$serviceAddress$serviceName$serviceApi";
// 用Map统一管理query参数
Map<String, String> queryParams = {};
if (key != null && key.isNotEmpty) {
queryParams['key'] = key;
}
if (group != null && group.isNotEmpty) {
queryParams['group'] = group;
}
if (bindType != null) {
queryParams['bindType'] = bindType.toString();
}
String? language = "";
if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code;
}
if (language != null && language.isNotEmpty) {
queryParams['lang'] = language;
}
// 拼接完整URL
if (queryParams.isNotEmpty) {
queryUrl += '?' + Uri(queryParameters: queryParams).query;
}
var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) {
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
MyUtils.formatResponse(res, "设备.设备列表请求成功".tr, "设备.设备列表请求失败".tr);
if (res.code == HttpStatusCodes.ok) {
deviceListForWeb.value = res.data!;
updateAll();
return res;
}
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
return apiResponse;
} catch (e) {
EasyDartModule.logger.info("设备请求列表: $e");
DailyLogUtils.writeLog("设备请求列表: $e");
}
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
Future<ApiResponse> deleteDevice(Map<String, dynamic> device) async { Future<ApiResponse> deleteDevice(Map<String, dynamic> device) async {
try { try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr); ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
@@ -428,6 +492,7 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
}, },
); );
} }
Future<void> getHomeSleeps(String? mac) async { Future<void> getHomeSleeps(String? mac) async {
String serviceAddress = ServiceConstant.service_address; String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service; String serviceName = ServiceConstant.server_service;
@@ -495,4 +560,79 @@ class MHTHomeController extends GetControllerEx<MHTHomeModel> {
}, },
); );
} }
//开启定时器
void startTimer(args) {
var tmp = args[0];
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.user_setting;
String type = "control_${tmp['mac']}";
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
var data = {
"type": type,
"duration": tmp['duration'],
"mac": tmp['mac'],
"time": tmp['startTime'],
};
requestWithLog(
logTitle: "更新控制倒计时",
method: MyHttpMethod.put,
queryUrl: queryUrl,
data: data,
onSuccess: (res) {});
}
//关闭定时器
void cancelTimer(args) {
var tmp = args[0];
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.user_setting;
String type = "control_${tmp['mac']}";
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
var data = {
"type": type,
"duration": 0,
"mac": tmp['mac'],
"time": tmp['startTime'],
};
requestWithLog(
logTitle: "查询控制倒计时",
method: MyHttpMethod.put,
queryUrl: queryUrl,
data: data,
onSuccess: (res) {});
}
//恢复
restoreTimer(args) async {
var data = {};
try {
var tmp = args[0];
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.user_setting;
String type = "control_${tmp}";
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?type=$type";
await requestWithLog(
logTitle: "查询控制倒计时",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
if (res.data != null) {
data = res.data;
}
},
onFailure: (res) {
data = {};
},
);
} catch (e) {
ef.log("$e");
}
return data;
}
} }

View File

@@ -273,6 +273,7 @@ class _MhtSleepReportPageState extends State<MhtSleepReportPage> {
'backgroundImg': 'backgroundImg':
'assets/images/new_background.png', 'assets/images/new_background.png',
'arrow': false, 'arrow': false,
'noBackImg':true,
}, },
), ),
); );

View File

@@ -115,6 +115,39 @@ class _NewHomePageState extends State<NewHomePage> {
// deviceController.getSleepReport(); // deviceController.getSleepReport();
} }
}); });
if (userInfoController.model.login == 1) {
//查询人员信息列表
deviceController.getPersonList();
//请求绑定设备列表
// homeController.getSleepReport();
deviceController.getDeviceNum().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
});
deviceController.getDeviceList(group: 'room').then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
} else {
//请求睡眠报告
// deviceController.getSleepReport();
}
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (homeController.homeSleepDays.value.isNotEmpty) {
homeController.selectedDayIndex.value =
homeController.homeSleepDays.value.length - 1;
}
});
int login = userInfoController.model.login!; int login = userInfoController.model.login!;
return GestureDetector( return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
@@ -138,7 +171,14 @@ class _NewHomePageState extends State<NewHomePage> {
children: [ children: [
// 左侧头像 // 左侧头像
Obx(() { Obx(() {
return userInfo(userInfoController.model.login); return InkWell(
onTap: () {
if (userInfoController.model.login == 0) {
Get.toNamed("/loginPage");
}
},
child: userInfo(userInfoController.model.login),
);
}), }),
const Spacer(), // 左右分隔 const Spacer(), // 左右分隔
FloatingSvgIcon( FloatingSvgIcon(
@@ -332,7 +372,7 @@ class _NewHomePageState extends State<NewHomePage> {
MediaQuery.sizeOf(context).height * MediaQuery.sizeOf(context).height *
0.184, 0.184,
constraints: BoxConstraints( constraints: BoxConstraints(
minHeight: 350.rpx, minHeight: 354.rpx,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: stringToColor("#003058"), color: stringToColor("#003058"),
@@ -345,8 +385,8 @@ class _NewHomePageState extends State<NewHomePage> {
Padding( Padding(
padding: padding:
EdgeInsetsDirectional.fromSTEB( EdgeInsetsDirectional.fromSTEB(
30.rpx, 20.rpx,
16.rpx, 20.rpx,
16.rpx, 16.rpx,
25.rpx), 25.rpx),
child: Container( child: Container(
@@ -786,10 +826,15 @@ class _NewHomePageState extends State<NewHomePage> {
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon( // Icon(
Icons.add, // Icons.add,
size: 60.rpx, // size: 60.rpx,
color: stringToColor("#85F5FF"), // color: stringToColor("#85F5FF"),
// ),
SvgPicture.asset(
'assets/images/icon/add.svg',
width: 42.rpx,
height: 42.rpx,
), ),
SizedBox(width: 20.rpx), SizedBox(width: 20.rpx),
Text( Text(

View File

@@ -64,7 +64,7 @@ class IssueListPage extends GetView<IssueListController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -27,12 +27,12 @@ class IssuePreviewWidget extends GetView<IssuePreviewInfoController> {
// await Future.delayed(Duration(milliseconds: 100)); // await Future.delayed(Duration(milliseconds: 100));
// issueListController.model.selectedIndex = -1; // issueListController.model.selectedIndex = -1;
// issueListController.updateAll(); // issueListController.updateAll();
// var article = issueListController.model.issueList![index]; var article = issueListController.model.issueList![index];
// Get.toNamed("/helpArticle", arguments: article); Get.toNamed("/helpArticle", arguments: article);
TopSlideNotification.show( // TopSlideNotification.show(
context, // context,
text: "功能开发中...", // text: "功能开发中...",
); // );
}, },
child: Obx(() { child: Obx(() {
return Container( return Container(

View File

@@ -0,0 +1,262 @@
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/appFontsize.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/message_controller.dart';
import 'package:vbvs_app/controller/mh_controller/mhdevice_share_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
class MessageDetailPage extends StatefulWidget {
final data;
const MessageDetailPage({super.key, required this.data});
@override
_MessageDetailPageState createState() => _MessageDetailPageState();
}
class _MessageDetailPageState extends State<MessageDetailPage> {
MHDeviceShareController controller = Get.find();
MhMessageController messageController = Get.find();
@override
Widget build(BuildContext context) {
var messageInfo = widget.data;
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image:
AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme:
IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'消息详情',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 0.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: const [],
centerTitle: false,
),
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.only(top: 30.rpx),
child: Column(
children: [
Padding(
padding:
EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Container(
decoration: BoxDecoration(
color: Color(0XFF003058),
borderRadius: BorderRadius.circular(16.rpx),
),
child: Padding(
padding: EdgeInsets.only(
left: 30.rpx,
top: 20.rpx,
bottom: 20.rpx),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
constraints: BoxConstraints(
minHeight: 66.rpx),
child: Align(
alignment:
AlignmentDirectional(-1, 0),
child: Text(
"${messageInfo['data']['title']}",
style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController
.currentColor.sc3,
),
),
),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
constraints: BoxConstraints(
minWidth: 30.rpx,
maxWidth: 140.rpx),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: messageInfo['data']
['val']
.map<Widget>((mapItem) =>
_buildInfoItem(
context,
mapItem['k'] ??
''))
.toList(),
),
),
Container(
constraints: BoxConstraints(
minWidth: 30.rpx),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: messageInfo['data']
['val']
.map<Widget>((mapItem) =>
_buildValueItem(
context,
mapItem['v'] ??
''))
.toList(),
),
),
].divide(SizedBox(width: 30.rpx)),
),
],
))),
),
const Spacer(),
bottomIcon(context)
],
)),
),
),
),
));
}
Container bottomIcon(BuildContext context) {
return Container(
height: 120.rpx,
decoration: BoxDecoration(
color: Color(0xFF003058),
),
width: double.infinity,
child: TextButton(
onPressed: () async {
if (widget.data['status'] == 1) {
ApiResponse apiResponse =
await controller.confirmShare(widget.data['data']['shareCode']);
if (apiResponse.code == HttpStatusCodes.ok) {
TopSlideNotification.show(context,
text: apiResponse.msg!, textColor: Color(0xFF00C1AA));
messageController.getMessageList();
messageController.updateAll();
} else {
TopSlideNotification.show(context,
text: apiResponse.msg!, textColor: Color(0XFFFF7159));
messageController.getMessageList();
messageController.updateAll();
}
}
},
child: Text(
getStatusText(widget.data['status']),
style: TextStyle(
fontFamily: 'Readex Pro',
color: widget.data['data']['status'] == 1
? Colors.white
: Color(0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
);
}
Widget _buildInfoItem(BuildContext context, String label) {
return Container(
constraints: BoxConstraints(
minHeight: 62.rpx,
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
overflow: TextOverflow.ellipsis,
maxLines: 1,
label.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
);
}
Widget _buildValueItem(BuildContext context, value) {
return Container(
constraints: BoxConstraints(
minHeight: 62.rpx,
),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
overflow: TextOverflow.ellipsis,
maxLines: 1,
"${value}",
style: TextStyle(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
);
}
String getStatusText(int status) {
switch (status) {
case 1:
return '同意';
case 2:
return '已同意';
case 3:
return '已过期';
default:
return '未知状态';
}
}
}

View File

@@ -175,7 +175,7 @@ class _MessagePageState extends State<MessagePage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -261,6 +261,7 @@ class _MessagePageState extends State<MessagePage> {
), ),
), ),
); );
} }
Container bottomIcon(BuildContext context) { Container bottomIcon(BuildContext context) {

View File

@@ -88,7 +88,7 @@ class _MyExperiencePageState extends State<MyExperiencePage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -141,7 +141,7 @@ class _MinePageState extends State<NewMinePage> {
userInfoController userInfoController
.model.user!.avatar!.isEmpty .model.user!.avatar!.isEmpty
? Image.asset( ? Image.asset(
"assets/images/people_avatar.png", "assets/images/default_avatar.png",
fit: BoxFit.cover, fit: BoxFit.cover,
) )
: Image.network( : Image.network(
@@ -149,7 +149,7 @@ class _MinePageState extends State<NewMinePage> {
fit: BoxFit.cover, fit: BoxFit.cover,
)) ))
: Image.asset( : Image.asset(
"assets/images/people_avatar.png", "assets/images/default_avatar.png",
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@@ -250,7 +250,7 @@ class _MinePageState extends State<NewMinePage> {
), ),
), ),
child: Text( child: Text(
'我的智能', '我的智能设备'.tr,
style: TextStyle( style: TextStyle(
fontSize: 26.rpx, color: const Color(0xFF003058)), fontSize: 26.rpx, color: const Color(0xFF003058)),
), ),

View File

@@ -63,7 +63,7 @@ class _SettingPageState extends State<SettingPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -288,7 +288,9 @@ class _SettingPageState extends State<SettingPage> {
.currentColor.sc21, // 点击时的背景色 .currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx), 0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {}, onTap: () {
Get.toNamed('/aboutUs');
},
child: Container( child: Container(
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
@@ -335,8 +337,7 @@ class _SettingPageState extends State<SettingPage> {
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx), 40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () { onTap: () {
TopSlideNotification.show(context, Get.toNamed("/userAgreementPage");
text: "待开发功能".tr);
}, },
child: Container( child: Container(
child: Padding( child: Padding(
@@ -384,8 +385,7 @@ class _SettingPageState extends State<SettingPage> {
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx), 0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () { onTap: () {
TopSlideNotification.show(context, Get.toNamed("/privacyPolicyPage");
text: "待开发功能".tr);
}, },
child: Container( child: Container(
child: Padding( child: Padding(
@@ -568,8 +568,10 @@ class _SettingPageState extends State<SettingPage> {
), ),
), ),
Text( Text(
AppConstants().ent_type == 1? 'Copyright © 202-2025 嘉兴太和信息技术有限责任公司 版权所有' AppConstants().ent_type == 1
.tr:"Copyright © 202-2025 杭州欢睡科技有限公司 版权所有", ? 'Copyright © 202-2025 嘉兴太和信息技术有限责任公司 版权所有'
.tr
: "Copyright © 202-2025 杭州欢睡科技有限公司 版权所有",
style: TextStyle( style: TextStyle(
color: themeController.currentColor.sc4, color: themeController.currentColor.sc4,
fontFamily: 'Inter', fontFamily: 'Inter',

View File

@@ -4,10 +4,12 @@ import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.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/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/TopSlideNotification.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/mh_controller/people_info_controller.dart'; import 'package:vbvs_app/controller/mh_controller/people_info_controller.dart';
@@ -58,7 +60,7 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
children: [ children: [
// 中间居中的标题 // 中间居中的标题
Text( Text(
'人员资料', '人员资料'.tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@@ -67,7 +69,7 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
Positioned( Positioned(
@@ -89,7 +91,9 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
d['height'].toString().isNotEmpty && d['height'].toString().isNotEmpty &&
int.tryParse(d['height'].toString()) == int.tryParse(d['height'].toString()) ==
null) { null) {
showToast("$prefix身高请输入数字"); TopSlideNotification.show(context,
text: "请选择身高".tr,
textColor: Color(0xFFFF7159));
isValid = false; isValid = false;
break; break;
} }
@@ -98,16 +102,9 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
d['weight'].toString().isNotEmpty && d['weight'].toString().isNotEmpty &&
int.tryParse(d['weight'].toString()) == int.tryParse(d['weight'].toString()) ==
null) { null) {
showToast("$prefix体重请输入数字"); TopSlideNotification.show(context,
isValid = false; text: "请选择体重".tr,
break; textColor: Color(0xFFFF7159));
}
if (d['tel'] != null &&
d['tel'].toString().isNotEmpty &&
!MyUtils.isValidPhoneNumber(
d['tel'].toString())) {
showToast("$prefix请输入正确的电话");
isValid = false; isValid = false;
break; break;
} }
@@ -116,7 +113,9 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
d['contact'].toString().isNotEmpty && d['contact'].toString().isNotEmpty &&
!MyUtils.isValidPhoneNumber( !MyUtils.isValidPhoneNumber(
d['contact'].toString())) { d['contact'].toString())) {
showToast("$prefix请输入正确的紧急联系人电话"); TopSlideNotification.show(context,
text: "请输入正确的联系人电话".tr,
textColor: Color(0xFFFF7159));
isValid = false; isValid = false;
break; break;
} }
@@ -126,13 +125,15 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
if (isValid) { if (isValid) {
for (var data in controller.model.peopleList) { for (var data in controller.model.peopleList) {
try { try {
await controller.savePeoples( await controller.savePeoples(data);
data); // 注意:你这个方法名是 savePeoples建议改成 savePerson TopSlideNotification.show(context,
showToast("保存成功(${data['mac']}", text: "更新成功".tr,
color: color_success); textColor: Color(0XFF00C1AA));
} catch (e) { } catch (e) {
print("保存失败:$e"); print("保存失败:$e");
showToast("保存失败(${data['mac']}"); TopSlideNotification.show(context,
text: "更新失败".tr,
textColor: Color(0xFFFF7159));
} }
} }
} }
@@ -153,7 +154,7 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
// color: stringToColor("#182B7C"), // color: stringToColor("#182B7C"),
// ), // ),
child: Text( child: Text(
"保存", "保存".tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Color(0XFF011D33), color: Color(0XFF011D33),
@@ -391,12 +392,16 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
SizedBox( SizedBox(
width: 16.rpx, width: 16.rpx,
), ),
Icon( Container(
Icons.expand_more, height: 30.rpx,
color: width: 30.rpx,
Colors.white, child:
size: 48.rpx, SvgPicture
), .asset(
'assets/img/icon/expand_more.svg',
color: Colors
.white,
))
], ],
), ),
], ],
@@ -560,11 +565,15 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
), ),
SizedBox( SizedBox(
width: 16.rpx), width: 16.rpx),
Icon( Container(
Icons.expand_more, height: 30.rpx,
color: width: 30.rpx,
Colors.white, child: SvgPicture
size: 48.rpx), .asset(
'assets/img/icon/expand_more.svg',
color: Colors
.white,
))
], ],
), ),
], ],
@@ -649,12 +658,16 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
), ),
SizedBox( SizedBox(
width: 16.rpx), width: 16.rpx),
Icon( Container(
Icons height: 30.rpx,
.expand_more, width: 30.rpx,
color: Colors child:
.white, SvgPicture
size: 48.rpx), .asset(
'assets/img/icon/expand_more.svg',
color: Colors
.white,
))
], ],
), ),
], ],
@@ -769,12 +782,16 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
SizedBox( SizedBox(
width: 16.rpx, width: 16.rpx,
), ),
Icon( Container(
Icons.expand_more, height: 30.rpx,
color: width: 30.rpx,
Colors.white, child:
size: 48.rpx, SvgPicture
), .asset(
'assets/img/icon/expand_more.svg',
color: Colors
.white,
))
], ],
), ),
], ],

View File

@@ -0,0 +1,121 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.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/setting/pdf/PrivacyPdfController.dart';
class PrivacyPolicyPage extends StatefulWidget {
PrivacyPolicyPage({super.key});
@override
State<PrivacyPolicyPage> createState() => _PrivacyPolicyPageState();
}
class _PrivacyPolicyPageState extends State<PrivacyPolicyPage> {
PrivacyPdfController pdfController = Get.find();
@override
void initState() {
super.initState();
String language = "zh_CN"; // 默认语言
int ent_type = AppConstants().ent_type;
if (languageController.selectLanguage?.value?.language_code != null) {
language = languageController.selectLanguage!.value!.language_code!;
} // 根据 ent_type 拼接不同的文件名
String pdfName =
ent_type == 1 ? "$language.pdf" : "${language}_$ent_type.pdf";
pdfController.loadPdf(
2,
"https://vsbst-api.he-info.cn/vsbs_sotrage/privacy-scheme/$pdfName",
);
}
@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/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'隐私协议'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 0.rpx),
child: Column(
children: [
Expanded(
child: Obx(() {
if (pdfController.localPdfPath.value == null) {
return Center(child: CircularProgressIndicator());
} else {
return PDFView(
filePath: pdfController.localPdfPath.value!,
autoSpacing: false,
enableSwipe: true,
swipeHorizontal: false,
pageSnap: true,
fitEachPage: true,
defaultPage: 0,
onRender: (pages) => print('PDF 渲染完成,共 $pages'),
onError: (error) => print('PDF 加载错误: $error'),
);
}
}),
),
],
),
),
),
),
),
),
);
}
}

View File

@@ -106,7 +106,7 @@ class RepairHistoryListPage extends GetView<RepairInfoController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -3,6 +3,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/mh_controller/apply_repair_controller.dart'; import 'package:vbvs_app/controller/mh_controller/apply_repair_controller.dart';
import 'package:vbvs_app/controller/mh_controller/repair_list_controller.dart'; import 'package:vbvs_app/controller/mh_controller/repair_list_controller.dart';
@@ -75,7 +76,7 @@ class DeviceRepairPage extends GetView<RepairListController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -257,7 +258,7 @@ class DeviceRepairPage extends GetView<RepairListController> {
)) ))
.toList(), .toList(),
) )
: EmptyMessageWidget(); : NullDataWidget();
}), }),
), ),
], ],

View File

@@ -5,6 +5,9 @@ import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh_controller/device_list_controller.dart';
import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart';
class RoomPickerPage extends StatefulWidget { class RoomPickerPage extends StatefulWidget {
final Map data; final Map data;
@@ -16,7 +19,7 @@ class RoomPickerPage extends StatefulWidget {
class _RoomPickerPageState extends State<RoomPickerPage> { class _RoomPickerPageState extends State<RoomPickerPage> {
late Map<String, dynamic> editedData; late Map<String, dynamic> editedData;
RxList rooms = [].obs; RxList rooms = [].obs;
DeviceListController deviceListController = Get.find();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -79,7 +82,7 @@ class _RoomPickerPageState extends State<RoomPickerPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -186,7 +189,25 @@ class _RoomPickerPageState extends State<RoomPickerPage> {
"roomId": rooms[selectedIndex]['_id'], "roomId": rooms[selectedIndex]['_id'],
}, },
onSuccess: (res) { onSuccess: (res) {
'更新人员信息成功: $res';
TopSlideNotification.show(context,
text: "更新成功".tr,
textColor: Color(0XFF00C1AA));
deviceListController.getDeviceList();
try {
WebviewTestController
webviewTestController = Get.find();
webviewTestController.web.jsbridge?.dart
.alterDevice();
} catch (e) {
ef.log("[h5]通知列表更新错误:$e");
}
Get.back(result:editedData);
},
onFailure: (res) {
TopSlideNotification.show(context,
text: "更新失败".tr,
textColor: Color(0xFFFF7159));
}, },
); );
} catch (e) { } catch (e) {
@@ -207,7 +228,7 @@ class _RoomPickerPageState extends State<RoomPickerPage> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
), ),
child: Text("完成", child: Text("完成".tr,
style: TextStyle( style: TextStyle(
color: const Color(0xFF003058), color: const Color(0xFF003058),
fontSize: 30.rpx, fontSize: 30.rpx,

View File

@@ -42,7 +42,7 @@ class ScorePage extends GetView<mh.ScoreController> {
children: [ children: [
// 中间居中的标题 // 中间居中的标题
Text( Text(
'评价', '评价'.tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@@ -51,7 +51,7 @@ class ScorePage extends GetView<mh.ScoreController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -107,7 +107,7 @@ class ScorePage extends GetView<mh.ScoreController> {
alignment: alignment:
AlignmentDirectional(0, 0), AlignmentDirectional(0, 0),
child: Text( child: Text(
'我要评价', '我要评价'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
fontSize: 30.rpx, fontSize: 30.rpx,

View File

@@ -117,6 +117,9 @@ class SearchWidget extends GetView {
// validator: _model // validator: _model
// .textControllerValidator // .textControllerValidator
// .asValidator(context), // .asValidator(context),
onChanged: (d) {
onChange?.call(d);
},
), ),
), ),
), ),
@@ -125,29 +128,33 @@ class SearchWidget extends GetView {
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 0, 0, 0), padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 0, 0, 0),
child: Row( child: InkWell(
mainAxisSize: MainAxisSize.max, onTap: () {
children: [ findCallback?.call();
SizedBox( },
height: 30.rpx, child: Row(
child: VerticalDivider( mainAxisSize: MainAxisSize.max,
thickness: 2.rpx, children: [
color: stringToColor("#333333"), //固定 SizedBox(
), height: 30.rpx,
child: VerticalDivider(
thickness: 2.rpx,
color: stringToColor("#333333"), //固定
),
),
Text(
'搜索'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: stringToColor("#333333"), //固定
),
),
].divide(SizedBox(width: 26.rpx)),
), ),
Text( )),
'搜索'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: stringToColor("#333333"), //固定
),
),
].divide(SizedBox(width: 26.rpx)),
),
),
], ],
), ),
), ),

View File

@@ -40,7 +40,7 @@ class _SleepHabitPageState extends State<SleepHabitPage> {
children: [ children: [
// 中间居中的标题 // 中间居中的标题
Text( Text(
'设备报修', '睡眠习惯'.tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@@ -49,7 +49,7 @@ class _SleepHabitPageState extends State<SleepHabitPage> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -77,7 +77,7 @@ class _SleepHabitPageState extends State<SleepHabitPage> {
width: bodysize!.maxWidth * 1, width: bodysize!.maxWidth * 1,
height: bodysize!.maxHeight * 0.056, height: bodysize!.maxHeight * 0.056,
child: Text( child: Text(
'柔性唤醒', '柔性唤醒'.tr,
style: TextStyle( style: TextStyle(
fontSize: 26.rpx, color: Colors.white), fontSize: 26.rpx, color: Colors.white),
))), ))),
@@ -95,7 +95,7 @@ class _SleepHabitPageState extends State<SleepHabitPage> {
width: bodysize!.maxWidth * 1, width: bodysize!.maxWidth * 1,
height: bodysize!.maxHeight * 0.056, height: bodysize!.maxHeight * 0.056,
child: Text( child: Text(
'睡眠隐私', '睡眠隐私'.tr,
style: TextStyle( style: TextStyle(
fontSize: 26.rpx, color: Colors.white), fontSize: 26.rpx, color: Colors.white),
))) )))

View File

@@ -66,7 +66,7 @@ class Smys extends GetView<SleepingHabitController> {
children: [ children: [
// 中间居中的标题 // 中间居中的标题
Text( Text(
'睡眠隐私', '睡眠隐私'.tr,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@@ -75,7 +75,7 @@ class Smys extends GetView<SleepingHabitController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],
@@ -125,7 +125,7 @@ class Smys extends GetView<SleepingHabitController> {
MainAxisAlignment.spaceBetween, MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'睡眠隐私功能', '睡眠隐私功能'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7), color: Color(0xFF9EA4B7),
@@ -156,52 +156,52 @@ class Smys extends GetView<SleepingHabitController> {
), ),
)), )),
// getLine(), // getLine(),
Container( InkWell(
width: double.infinity, onTap: () async {
height: MediaQuery.sizeOf(context).height * 0.055, showDayTimeSelectionDialog(context,
decoration: BoxDecoration( dayTimeArr: controller.model.smysStartTime,
border: Border( title: "开始时间".tr, checkChange: (d) {
bottom: BorderSide( controller.attr.update((getmodel) {
color: const Color(0xFF929699), getmodel.model.smysStartTime = [
width: 0.rpx), int.parse("${d[0]}"),
int.parse("${d[1]}")
];
});
// updateParm();
});
},
child: Container(
width: double.infinity,
height:
MediaQuery.sizeOf(context).height * 0.055,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: const Color(0xFF929699),
width: 0.rpx),
),
), ),
), constraints: BoxConstraints(
constraints: BoxConstraints( minHeight: 90.rpx, // 设置最小高度
minHeight: 90.rpx, // 设置最小高度 ),
), child: Padding(
child: Padding( padding: EdgeInsets.fromLTRB(
padding: EdgeInsets.fromLTRB( 39.rpx, 0.rpx, 30.rpx, 0.rpx),
39.rpx, 0.rpx, 30.rpx, 0.rpx), child: Row(
child: Row( mainAxisSize: MainAxisSize.max,
mainAxisSize: MainAxisSize.max, mainAxisAlignment:
mainAxisAlignment: MainAxisAlignment.spaceBetween,
MainAxisAlignment.spaceBetween, children: [
children: [ Text(
Text( '开始时间'.tr,
'开始时间', style: TextStyle(
style: TextStyle( fontFamily: 'Readex Pro',
fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7),
color: Color(0xFF9EA4B7), fontSize: 26.rpx,
fontSize: 26.rpx, letterSpacing: 0,
letterSpacing: 0, ),
), ),
), Row(
InkWell(
onTap: () async {
showDayTimeSelectionDialog(context,
dayTimeArr:
controller.model.smysStartTime,
title: "开始时间", checkChange: (d) {
controller.attr.update((getmodel) {
getmodel.model.smysStartTime = [
int.parse("${d[0]}"),
int.parse("${d[1]}")
];
});
// updateParm();
});
},
child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Text( Text(
@@ -225,57 +225,56 @@ class Smys extends GetView<SleepingHabitController> {
)) ))
], ],
), ),
), ],
],
),
)),
// getLine(),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.055,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: const Color(0xFF929699),
width: 0.rpx),
),
),
constraints: BoxConstraints(
minHeight: 90.rpx, // 设置最小高度
),
child: Padding(
padding: EdgeInsets.fromLTRB(
39.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'结束时间',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 26.rpx,
letterSpacing: 0,
),
), ),
InkWell( )),
onTap: () async { ),
showDayTimeSelectionDialog(context, // getLine(),
dayTimeArr: InkWell(
controller.model.smysEndTime, onTap: () async {
title: "结束时间", checkChange: (d) { showDayTimeSelectionDialog(context,
controller.attr.update((getmodel) { dayTimeArr: controller.model.smysEndTime,
getmodel.model.smysEndTime = [ title: "结束时间".tr, checkChange: (d) {
int.parse("${d[0]}"), controller.attr.update((getmodel) {
int.parse("${d[1]}") getmodel.model.smysEndTime = [
]; int.parse("${d[0]}"),
}); int.parse("${d[1]}")
// updateParm(); ];
}); });
}, // updateParm();
child: Row( });
},
child: Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.055,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: const Color(0xFF929699),
width: 0.rpx),
),
),
constraints: BoxConstraints(
minHeight: 90.rpx, // 设置最小高度
),
child: Padding(
padding: EdgeInsets.fromLTRB(
39.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'结束时间'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Text( Text(
@@ -299,12 +298,11 @@ class Smys extends GetView<SleepingHabitController> {
)) ))
], ],
), ),
), ],
], ),
), ),
), ),
), ), // getLine(),
// getLine(),
SizedBox( SizedBox(
height: 30.rpx, height: 30.rpx,
), ),
@@ -314,7 +312,7 @@ class Smys extends GetView<SleepingHabitController> {
width: double.infinity, width: double.infinity,
decoration: BoxDecoration(), decoration: BoxDecoration(),
child: Text( child: Text(
'*注:开启睡眠隐私功能后,在设置的时间段内,将不会采集您的睡眠数据。', '*注:开启睡眠隐私功能后,在设置的时间段内,将不会采集您的睡眠数据。'.tr,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7), color: Color(0xFF9EA4B7),

View File

@@ -1,9 +1,16 @@
import 'dart:async';
import 'dart:convert';
import 'package:EasyDartModule/EasyDartModule.dart' as edm;
import 'package:easydevice/easydevice.dart';
import 'package:easyweb/base/easyws.dart';
import 'package:easyweb/base/minisdk.dart';
import 'package:easyweb/easyweb.dart'; import 'package:easyweb/easyweb.dart';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:easyweb/base/minisdk.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:easydevice/easydevice.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart';
@@ -16,14 +23,18 @@ class WebviewTestModel {
} }
class WebviewTestController extends GetControllerEx<WebviewTestModel> { class WebviewTestController extends GetControllerEx<WebviewTestModel> {
var selectDevice; var selectDevice = {};
var bluetooth = false; var lastSelectDevice = {};
var bluetooth = 0;
List personList = [];
List instantData = [];
WebviewTestController() : super(WebviewTestModel()) { WebviewTestController() : super(WebviewTestModel()) {
web = WebviewHelper( web = WebviewHelper(
jsbridge: buildsdk( jsbridge: buildsdk(
father: this, // father: this,
// clientId: '494641114', // clientId: '494641114',
//dbgserverUrl: 'ws://192.168.1.2:9001', // dbgserverUrl: 'ws://192.168.1.2:9001',
), ),
settings: buildsettings(), settings: buildsettings(),
params: PlatformHeadlessInAppWebViewCreationParams( params: PlatformHeadlessInAppWebViewCreationParams(
@@ -46,12 +57,32 @@ class WebviewTestController extends GetControllerEx<WebviewTestModel> {
bridge.sdk.updateDeviceRoute((args) async { bridge.sdk.updateDeviceRoute((args) async {
ef.log('updateDeviceRoute: $args'); ef.log('updateDeviceRoute: $args');
selectDevice['blueToothStatus'] = bluetooth; selectDevice['blueToothStatus'] = bluetooth;
Get.toNamed("$args[0]", arguments: selectDevice); Get.toNamed("${args[0]}", arguments: selectDevice);
return true; return true;
}); });
bridge.sdk.selectDevice((args) async { bridge.sdk.selectDevice((args) async {
<<<<<<< HEAD
ef.log('selectDevice: $args'); ef.log('selectDevice: $args');
selectDevice = args[0]; selectDevice = args[0];
=======
try {
ef.log('selectDevice: $args');
selectDevice = args[0];
await queryPersonInfoByMac();
if (selectDevice != null &&
selectDevice.isNotEmpty &&
selectDevice['mac'] != null &&
(selectDevice['mac'] != args[0]['mac'])) {
lastSelectDevice = selectDevice;
}
dealInstantData(selectDevice);
} catch (e) {
ef.log("[aaaa]$e");
}
//查询人员信息
>>>>>>> 13eb25e1c30dcd81c87aa85bcb5306ca0931ed21
return true; return true;
}); });
bridge.sdk.updateBlueToothStatus((args) async { bridge.sdk.updateBlueToothStatus((args) async {
@@ -59,6 +90,57 @@ class WebviewTestController extends GetControllerEx<WebviewTestModel> {
bluetooth = args[0]; bluetooth = args[0];
return true; return true;
}); });
//sdk定义接口
bridge.sdk.querySelectDevice((args) async {
ef.log('updateBlueToothStatus: $args');
// bluetooth = args[0];
MHTHomeController deviceController = Get.find();
final allDevices = deviceController.deviceList.values
.expand((list) => list)
.toList();
return allDevices;
});
//请求token信息
bridge.sdk.queryUserToken((args) async {
ef.log('queryUserToken: $args');
// bluetooth = args[0];
return edm.EasyDartModule.dio.token;
});
//请求设备人员信息
bridge.sdk.queryPersonInfo((args) async {
ef.log('queryPersonInfo: $args');
// bluetooth = args[0];
return personList;
});
//请求实时体征数据
bridge.sdk.queryInstantData((args) async {
ef.log('queryInstantData: $args');
// bluetooth = args[0];
return instantData;
});
bridge.sdk.queryInstantData((args) async {
ef.log('queryInstantData: $args');
// bluetooth = args[0];
return instantData;
});
bridge.sdk.startTimer((args) async {
ef.log('queryInstantData: $args');
MHTHomeController homeController = Get.find();
homeController.startTimer(args);
return true;
});
bridge.sdk.cancelTimer((args) async {
ef.log('queryInstantData: $args');
MHTHomeController homeController = Get.find();
homeController.cancelTimer(args);
return true;
});
bridge.sdk.restoreTimer((args) async {
ef.log('queryInstantData: $args');
MHTHomeController homeController = Get.find();
var data = await homeController.restoreTimer(args);
return data;
});
}); });
web web
//.file( //.file(
@@ -80,6 +162,116 @@ class WebviewTestController extends GetControllerEx<WebviewTestModel> {
late WebviewHelper web; late WebviewHelper web;
var ready = false.obs; var ready = false.obs;
var cnt = 0.obs; var cnt = 0.obs;
Future<void> queryPersonInfoByMac() async {
UserInfoController userInfoController = Get.find();
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.person_info;
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?mac=${selectDevice['mac']}";
try {
final res = await requestWithLog(
logTitle: "查询设备绑定人员列表",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
personList = res.data;
});
} catch (e) {
print("查询设备绑定列表失败: $e");
}
}
void dealInstantData(selectDevice) {
//处理实时数据
// edm.EasyDartModule.websocket.sendData(
// jsonEncode(WebSocketMessage(path: "/vsbs/web/rt/marttress", type: 2)));
lastSelectDevice;
var ws;
ws = Easyws(
url: ServiceConstant.webSocketService,
onData: (data) {
ef.log("ws recv =>$data");
try {
var tmp;
if (data is String) {
tmp = jsonDecode(data); // 只有是 String 才 decode
} else if (data is Map<String, dynamic>) {
tmp = data; // 直接用
} else {
print("未知数据格式");
}
if (tmp['data'] != null && tmp['data'] is Map) {
var newData = tmp['data'];
var mac = newData['mac'];
if (mac != null) {
// 删除已有的同 mac 项
instantData.removeWhere((element) => element['mac'] == mac);
// 添加新的数据
instantData.add(newData);
}
}
} catch (e) {
ef.log("ws error =>$e");
}
},
onStateChange: (x) {
ef.log("ws =>$x");
if (x == EasywsState.connected) {
try {
if (lastSelectDevice != null && lastSelectDevice.isNotEmpty) {
List<String?> oldMacList = [
lastSelectDevice['bind_mac_a'],
lastSelectDevice['bind_mac_b'],
];
for (String? mac in oldMacList) {
if (mac != null && mac.isNotEmpty) {
bool success = ws.send({
"type": 2,
"path": "/vsbs/web/rt/marttress",
"data": {"mac": mac},
});
if (success) {
ef.log("✅ 已取消监听:$mac");
}
}
}
}
} catch (e) {
ef.log("❌ 取消旧设备监听失败: $e");
}
try {
// 2. 开始监听新设备A/B 都监听)
if (selectDevice != null && selectDevice.isNotEmpty) {
List<String?> newMacList = [
selectDevice['bind_mac_a'],
selectDevice['bind_mac_b'],
];
for (String? mac in newMacList) {
if (mac != null && mac.isNotEmpty) {
bool success = ws.send({
"type": 1,
"path": "/vsbs/web/rt/marttress",
"data": {"mac": mac},
});
if (success) {
ef.log("✅ 开始监听新设备:$mac");
}
}
}
// 更新记录
lastSelectDevice = selectDevice;
}
} catch (e) {
ef.log("❌ 监听新设备失败: $e");
}
}
},
);
ws.connect();
}
//EasyFlutter End //EasyFlutter End
} }
@@ -90,7 +282,7 @@ class WebviewTestView extends GetComponent<WebviewTestController> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
UserInfoController userInfoController = Get.find(); UserInfoController userInfoController = Get.find();
MHTHomeController deviceController = Get.find(); MHTHomeController deviceController = Get.find();
deviceController.getDeviceList(group: 'room').then((x) { deviceController.getDeviceList().then((x) {
if (controller.web.jsbridge!.inited) { if (controller.web.jsbridge!.inited) {
//发送测试消息给webview //发送测试消息给webview
controller.web.jsbridge!.dart controller.web.jsbridge!.dart

View File

@@ -82,7 +82,7 @@ class _UpdateUserPageState extends State<EditUserPage> {
), ),
), ),
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
Positioned( Positioned(

View File

@@ -70,7 +70,7 @@ class FindPasswordPage extends GetView<FindPasswordController> {
), ),
// 左侧图标 // 左侧图标
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,7 @@ class RegisterPage extends GetView<MHTRegisterController> {
), ),
), ),
Positioned( Positioned(
left: 20.rpx, left: 0.rpx,
child: returnIconButtomNew, child: returnIconButtomNew,
), ),
], ],

View File

@@ -219,52 +219,6 @@ class _RxhxMhtState extends State<RxhxMht> {
], ],
), ),
), ),
// leading: returnIconButtomAddCallback(() {
// controller.saveDataApi();
// }),
// Container(
// width: double.infinity,
// height: 70.rpx,
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '柔性唤醒',
// style: TextStyle(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// letterSpacing: 0,
// fontSize: 30.rpx),
// ),
// InkWell(
// onTap: () {
// alarmChange();
// },
// child: Container(
// margin: EdgeInsets.only(right: 30.rpx),
// width: 140.rpx,
// height: 66.rpx,
// alignment: Alignment.center,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(5),
// color: stringToColor("#182B7C")),
// child: Text(
// "保存",
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: stringToColor("#9EA4B7"),
// letterSpacing: 0,
// fontSize: 30.rpx),
// ),
// ),
// )
// ],
// ),
// ),
actions: [], actions: [],
centerTitle: false, centerTitle: false,
), ),
@@ -343,39 +297,40 @@ class _RxhxMhtState extends State<RxhxMht> {
), ),
), ),
getLine(), getLine(),
Container( InkWell(
margin: EdgeInsets.only(left: 40.rpx, right: 30.rpx), onTap: () async {
width: double.infinity, showDayTimeSelectionDialog(context,
height: 90.rpx, dayTimeArr: controller.model.rxhxWakeTime,
decoration: const BoxDecoration(), title: "唤醒时间", checkChange: (d) {
child: Row( controller.attr.update((getmodel) {
mainAxisSize: MainAxisSize.max, getmodel.model.rxhxWakeTime = [
mainAxisAlignment: MainAxisAlignment.spaceBetween, int.parse("${d[0]}"),
children: [ int.parse("${d[1]}")
Text( ];
'唤醒时间', });
style: TextStyle( print("$d");
fontFamily: 'Readex Pro', });
color: Colors.white, },
fontSize: 26.rpx, child: Container(
letterSpacing: 0, margin:
EdgeInsets.only(left: 40.rpx, right: 30.rpx),
width: double.infinity,
height: 90.rpx,
decoration: const BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'唤醒时间',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0,
),
), ),
), Row(
InkWell(
onTap: () async {
showDayTimeSelectionDialog(context,
dayTimeArr: controller.model.rxhxWakeTime,
title: "唤醒时间", checkChange: (d) {
controller.attr.update((getmodel) {
getmodel.model.rxhxWakeTime = [
int.parse("${d[0]}"),
int.parse("${d[1]}")
];
});
print("$d");
});
},
child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Text( Text(
@@ -399,133 +354,134 @@ class _RxhxMhtState extends State<RxhxMht> {
)) ))
], ],
), ),
), ],
], ),
), ),
), ),
getLine(), getLine(),
Container( InkWell(
margin: EdgeInsets.only(left: 40.rpx, right: 30.rpx), onTap: () {
width: double.infinity, showOneSelectionDialog(
height: 90.rpx, context,
decoration: const BoxDecoration(), arr: ['', ""],
child: Row( checkIndex: controller.model.rxhxIsAnMo ? 0 : 1,
mainAxisSize: MainAxisSize.max, title: "按摩",
mainAxisAlignment: MainAxisAlignment.spaceBetween, checkChange: (index) {
children: [ controller.attr.update((getmodel) {
Text( getmodel.model.rxhxIsAnMo =
'按摩', index == 0 ? true : false;
style: TextStyle( });
fontFamily: 'Readex Pro', },
color: Colors.white, );
fontSize: 26.rpx, },
letterSpacing: 0, child: Container(
), margin:
), EdgeInsets.only(left: 40.rpx, right: 30.rpx),
InkWell( width: double.infinity,
onTap: () { height: 90.rpx,
showOneSelectionDialog( decoration: const BoxDecoration(),
context, child: Row(
arr: ['', ""], mainAxisSize: MainAxisSize.max,
checkIndex: mainAxisAlignment:
controller.model.rxhxIsAnMo ? 0 : 1, MainAxisAlignment.spaceBetween,
title: "按摩", children: [
checkChange: (index) { Text(
controller.attr.update((getmodel) { '按摩',
getmodel.model.rxhxIsAnMo = style: TextStyle(
index == 0 ? true : false; fontFamily: 'Readex Pro',
}); color: Colors.white,
}, fontSize: 26.rpx,
); letterSpacing: 0,
},
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
controller.model.rxhxIsAnMo ? '' : '',
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0,
),
), ),
SizedBox( ),
width: 16.rpx, Row(
), mainAxisSize: MainAxisSize.max,
Container( children: [
height: 30.rpx, Text(
width: 30.rpx, controller.model.rxhxIsAnMo ? '' : '',
child: SvgPicture.asset( style: TextStyle(
'assets/img/icon/expand_more.svg', fontFamily: 'Readex Pro',
color: Colors.white, color: Colors.white,
)) fontSize: 26.rpx,
], letterSpacing: 0,
), ),
), ),
], SizedBox(
), width: 16.rpx,
),
Container(
height: 30.rpx,
width: 30.rpx,
child: SvgPicture.asset(
'assets/img/icon/expand_more.svg',
color: Colors.white,
))
],
),
],
)),
), ),
getLine(), getLine(),
Container( InkWell(
margin: EdgeInsets.only(left: 40.rpx, right: 30.rpx), onTap: () {
width: double.infinity, showOneSelectionDialog(
height: 90.rpx, context,
decoration: const BoxDecoration(), arr: location,
child: Row( checkIndex: controller.model.rxhxLocation,
mainAxisSize: MainAxisSize.max, title: "唤醒部位",
mainAxisAlignment: MainAxisAlignment.spaceBetween, checkChange: (index) {
children: [ controller.attr.update((getmodel) {
Text( getmodel.model.rxhxLocation = index;
'唤醒部位', });
style: TextStyle( },
fontFamily: 'Readex Pro', );
color: Colors.white, },
fontSize: 26.rpx, child: Container(
letterSpacing: 0, margin:
), EdgeInsets.only(left: 40.rpx, right: 30.rpx),
), width: double.infinity,
InkWell( height: 90.rpx,
onTap: () { decoration: const BoxDecoration(),
showOneSelectionDialog( child: Row(
context, mainAxisSize: MainAxisSize.max,
arr: location, mainAxisAlignment:
checkIndex: controller.model.rxhxLocation, MainAxisAlignment.spaceBetween,
title: "唤醒部位", children: [
checkChange: (index) { Text(
controller.attr.update((getmodel) { '唤醒部位',
getmodel.model.rxhxLocation = index; style: TextStyle(
}); fontFamily: 'Readex Pro',
}, color: Colors.white,
); fontSize: 26.rpx,
}, letterSpacing: 0,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
location[controller.model.rxhxLocation],
style: TextStyle(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0,
),
), ),
SizedBox( ),
width: 16.rpx, Row(
), mainAxisSize: MainAxisSize.max,
Container( children: [
height: 30.rpx, Text(
width: 30.rpx, location[controller.model.rxhxLocation],
child: SvgPicture.asset( style: TextStyle(
'assets/img/icon/expand_more.svg', fontFamily: 'Readex Pro',
color: Colors.white, color: Colors.white,
)) fontSize: 26.rpx,
], letterSpacing: 0,
), ),
), ),
], SizedBox(
), width: 16.rpx,
),
Container(
height: 30.rpx,
width: 30.rpx,
child: SvgPicture.asset(
'assets/img/icon/expand_more.svg',
color: Colors.white,
))
],
),
],
)),
), ),
getLine(), getLine(),
Container( Container(
@@ -550,65 +506,120 @@ class _RxhxMhtState extends State<RxhxMht> {
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 20.rpx, 0, 0),
// child: Container(
// width: double.infinity,
// height:
// MediaQuery.sizeOf(context).height * 0.046,
// decoration: const BoxDecoration(),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// ...List.generate(7, (index) {
// return InkWell(
// onTap: () {
// controller.attr.update((getmodel) {
// getmodel.model
// .rxhxWeeks[index] = getmodel
// .model
// .rxhxWeeks[index] ==
// 0
// ? 1
// : 0;
// });
// },
// child: AspectRatio(
// aspectRatio: 1,
// child: ClipOval(
// child: Container(
// height: double.infinity,
// decoration: BoxDecoration(
// color: controller.model
// .rxhxWeeks[
// index] ==
// 1
// ? Color(0xFF84F5FF)
// : Color(0XFF003058)),
// child: Center(
// child: Text(
// weeks[index],
// style: TextStyle(
// color: controller.model
// .rxhxWeeks[
// index] ==
// 1
// ? Color(0XFF003058)
// : Colors.white),
// ),
// ),
// ),
// ),
// ),
// );
// }),
// ],
// ),
// ),
// ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0, 20.rpx, 0, 0), 0, 20.rpx, 0, 0),
child: Container( child: SizedBox(
width: double.infinity, width: double.infinity,
height: height:
MediaQuery.sizeOf(context).height * 0.046, MediaQuery.sizeOf(context).height * 0.046,
decoration: const BoxDecoration(),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceBetween, MainAxisAlignment.spaceBetween,
children: [ children: List.generate(7, (index) {
...List.generate(7, (index) { final bool selected =
return InkWell( controller.model.rxhxWeeks[index] ==
onTap: () { 1;
controller.attr.update((getmodel) { return InkWell(
getmodel.model onTap: () {
.rxhxWeeks[index] = getmodel controller.attr.update((getmodel) {
.model getmodel.model.rxhxWeeks[index] =
.rxhxWeeks[index] == getmodel.model
0 .rxhxWeeks[index] ==
? 1 0
: 0; ? 1
}); : 0;
}, });
child: AspectRatio( },
aspectRatio: 1, borderRadius: BorderRadius.circular(
child: ClipOval( 50), // 点击水波圆角区域
child: Container( child: Container(
height: double.infinity, width: MediaQuery.sizeOf(context)
decoration: BoxDecoration( .height *
color: controller.model 0.046, // 保证是正圆
.rxhxWeeks[ height: MediaQuery.sizeOf(context)
index] == .height *
1 0.046,
? Color(0xFF84F5FF) decoration: BoxDecoration(
: Color(0XFF003058)), shape: BoxShape.circle,
child: Center( color: selected
child: Text( ? const Color(0xFF84F5FF)
weeks[index], : const Color(0xFF003058),
style: TextStyle( ),
color: controller.model alignment: Alignment.center,
.rxhxWeeks[ child: Text(
index] == weeks[index],
1 style: TextStyle(
? Color(0XFF003058) color: selected
: Colors.white), ? const Color(0xFF003058)
), : Colors.white,
),
),
), ),
), ),
); ),
}), );
], }),
), ),
), ),
), )
], ],
), ),
), ),
@@ -624,7 +635,7 @@ class _RxhxMhtState extends State<RxhxMht> {
'*注:开启该功能后,在设置的时间点,设备将启动一段固定时长的柔性唤醒功能。', '*注:开启该功能后,在设置的时间点,设备将启动一段固定时长的柔性唤醒功能。',
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: Colors.white, color: Color(0xFF929699),
fontSize: 20.rpx, fontSize: 20.rpx,
letterSpacing: 0, letterSpacing: 0,
), ),

View File

@@ -0,0 +1,126 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.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/setting/pdf/UserPdfController.dart';
class UserAgreementPage extends StatefulWidget {
UserAgreementPage({super.key});
@override
State<UserAgreementPage> createState() => _UserAgreementPageState();
}
class _UserAgreementPageState extends State<UserAgreementPage> {
UserPdfController pdfController = Get.find();
@override
void initState() {
super.initState();
String language = "zh_CN"; // 默认语言
if (languageController.selectLanguage?.value?.language_code != null) {
language = languageController.selectLanguage!.value!.language_code!;
}
int ent_type = AppConstants().ent_type;
// 根据 ent_type 拼接不同的文件名
String pdfName =
ent_type == 1 ? "$language.pdf" : "${language}_$ent_type.pdf";
pdfController.loadPdf(
1,
"https://vsbst-api.he-info.cn/vsbs_sotrage/user-scheme/$pdfName",
);
}
@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/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'用户协议'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
Positioned(
left: 0,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 0.rpx),
child: Column(
children: [
Expanded(
child: Obx(() {
if (pdfController.localPdfPath.value == null) {
return Center(child: CircularProgressIndicator());
} else {
return PDFView(
filePath: pdfController.localPdfPath.value!,
autoSpacing: false,
enableSwipe: true,
swipeHorizontal: false,
pageSnap: true,
fitEachPage: true,
defaultPage: 0,
onRender: (pages) => print('PDF 渲染完成,共 $pages'),
onError: (error) => print('PDF 加载错误: $error'),
);
}
}),
),
],
),
),
),
),
),
),
);
}
}

View File

@@ -179,8 +179,8 @@ class _MHTNewSleepReportPageState extends State<MHTNewSleepReportPage> {
if (widget.data['arrow'] == null || if (widget.data['arrow'] == null ||
widget.data['arrow'] == true) widget.data['arrow'] == true)
Positioned( Positioned(
left: 0, left: 20,
child: returnIconButtom, child: returnIconButtomNew,
), ),
], ],
), ),

View File

@@ -122,8 +122,8 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
/// 左边返回按钮 /// 左边返回按钮
Positioned( Positioned(
left: 0, left: 20,
child: returnIconButtom, child: returnIconButtomNew,
), ),
], ],
), ),

View File

@@ -13,6 +13,7 @@ import 'package:vbvs_app/controller/home/home_controller.dart';
import 'package:vbvs_app/controller/sleep/sleep_report_controller.dart'; import 'package:vbvs_app/controller/sleep/sleep_report_controller.dart';
import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/language/AppLanguage.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
import 'package:vbvs_app/pages/sleep_report/component/AIAdviceWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/AIAdviceWidget.dart';
import 'package:vbvs_app/pages/sleep_report/component/BreatheCard.dart'; import 'package:vbvs_app/pages/sleep_report/component/BreatheCard.dart';
import 'package:vbvs_app/pages/sleep_report/component/BreathePauseNewWidget.dart'; import 'package:vbvs_app/pages/sleep_report/component/BreathePauseNewWidget.dart';
@@ -91,8 +92,16 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
_scrollToTargetComponent(sleepReportController.sleepReport); _scrollToTargetComponent(sleepReportController.sleepReport);
}, },
onFailure: (res) { onFailure: (res) {
TopSlideNotification.show(context, if (MainPageBBottomChange.getCurrentIndex() != null) {
text: res.msg!, textColor: themeController.currentColor.sc9); if (MainPageBBottomChange.getCurrentIndex() == 1) {
TopSlideNotification.show(context,
text: res.msg!, textColor: themeController.currentColor.sc9);
}
} else {
TopSlideNotification.show(context,
text: res.msg!, textColor: themeController.currentColor.sc9);
}
sleepReportController.sleepReport.value = {}; sleepReportController.sleepReport.value = {};
sleepReportController.updateAll(); sleepReportController.updateAll();
print(res); print(res);
@@ -149,15 +158,28 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
builder: (context, bodySize) => GestureDetector( builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
child: Container( child: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: (widget.data['backgroundImg'] != null &&
// widget.data['backgroundImg'].toString().isNotEmpty)
// ? AssetImage(widget.data['backgroundImg'])
// : AssetImage('assets/img/bgNoImg.png') as ImageProvider,
// fit: BoxFit.fill,
// ),
// ),
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: (widget.data['noBackImg'] != null &&
image: (widget.data['backgroundImg'] != null && widget.data['noBackImg'] == true)
widget.data['backgroundImg'].toString().isNotEmpty) ? null // ✅ 不要背景图
? AssetImage(widget.data['backgroundImg']) : DecorationImage(
: AssetImage('assets/img/bgNoImg.png') as ImageProvider, image: (widget.data['backgroundImg'] != null &&
fit: BoxFit.fill, widget.data['backgroundImg'].toString().isNotEmpty)
), ? AssetImage(widget.data['backgroundImg'])
: AssetImage('assets/img/bgNoImg.png') as ImageProvider,
fit: BoxFit.fill,
),
), ),
child: Scaffold( child: Scaffold(
backgroundColor: Colors.transparent, // 背景透明 backgroundColor: Colors.transparent, // 背景透明
appBar: AppBar( appBar: AppBar(
@@ -189,7 +211,7 @@ class _NewSleepReportPageState extends State<NewSleepReportPage> {
widget.data['arrow'] == true) widget.data['arrow'] == true)
Positioned( Positioned(
left: 0, left: 0,
child: returnIconButtom, child: returnIconButtomNew,
), ),
], ],
), ),

View File

@@ -77,7 +77,7 @@ class _SleepReportPageState extends State<SleepReportPage> {
/// 左边返回按钮 /// 左边返回按钮
Positioned( Positioned(
left: 0, left: 0,
child: returnIconButtom, child: returnIconButtomNew,
), ),
], ],
), ),

View File

@@ -57,15 +57,13 @@ class _AboutUsPageState extends State<AboutUsPage> {
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
/// 居中标题 /// 居中标题
Text( Text('关于我们'.tr,
'关于我们'.tr, style: TextStyle(
style: TextStyle( fontFamily: 'Readex Pro',
fontFamily: 'Readex Pro', color: themeController.currentColor.sc3,
color: themeController.currentColor.sc3, letterSpacing: 0,
letterSpacing: 0, fontSize: 30.rpx,
fontSize: 30.rpx, )),
),
),
/// 左边返回按钮 /// 左边返回按钮
Positioned( Positioned(

View File

@@ -1,5 +1,6 @@
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:path/path.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
@@ -8,6 +9,8 @@ import 'package:vbvs_app/main.dart';
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
import 'package:vbvs_app/pages/mh_page/HomeDeviceType.dart'; import 'package:vbvs_app/pages/mh_page/HomeDeviceType.dart';
import 'package:vbvs_app/pages/mh_page/LanguagePage.dart'; import 'package:vbvs_app/pages/mh_page/LanguagePage.dart';
import 'package:vbvs_app/pages/mh_page/ShareDeviceDetailWidget.dart';
import 'package:vbvs_app/pages/mh_page/about_us.dart';
import 'package:vbvs_app/pages/mh_page/address_list_page.dart'; import 'package:vbvs_app/pages/mh_page/address_list_page.dart';
import 'package:vbvs_app/pages/mh_page/applyRepair/apply_repair_success.dart'; import 'package:vbvs_app/pages/mh_page/applyRepair/apply_repair_success.dart';
import 'package:vbvs_app/pages/mh_page/apply_repair_page.dart'; import 'package:vbvs_app/pages/mh_page/apply_repair_page.dart';
@@ -24,6 +27,8 @@ import 'package:vbvs_app/pages/mh_page/device_people_info.dart';
import 'package:vbvs_app/pages/mh_page/device_share_page.dart'; import 'package:vbvs_app/pages/mh_page/device_share_page.dart';
import 'package:vbvs_app/pages/mh_page/edit_bed.dart'; import 'package:vbvs_app/pages/mh_page/edit_bed.dart';
import 'package:vbvs_app/pages/mh_page/help/article.dart'; import 'package:vbvs_app/pages/mh_page/help/article.dart';
import 'package:vbvs_app/pages/mh_page/homepage/new_Home_page.dart';
import 'package:vbvs_app/pages/mh_page/privacy_policy.dart';
import 'package:vbvs_app/pages/mh_page/user/page/edit_userinfo_page.dart'; import 'package:vbvs_app/pages/mh_page/user/page/edit_userinfo_page.dart';
import 'package:vbvs_app/pages/mh_page/experience_store_page.dart'; import 'package:vbvs_app/pages/mh_page/experience_store_page.dart';
import 'package:vbvs_app/pages/mh_page/issue_list_page.dart'; import 'package:vbvs_app/pages/mh_page/issue_list_page.dart';
@@ -39,9 +44,11 @@ import 'package:vbvs_app/pages/mh_page/user/page/find_password_page.dart';
import 'package:vbvs_app/pages/mh_page/user/page/mht_login_page.dart'; import 'package:vbvs_app/pages/mh_page/user/page/mht_login_page.dart';
import 'package:vbvs_app/pages/mh_page/user/page/rxhx_mht.dart'; import 'package:vbvs_app/pages/mh_page/user/page/rxhx_mht.dart';
import 'package:vbvs_app/pages/mh_page/user/page/update_password_page.dart'; import 'package:vbvs_app/pages/mh_page/user/page/update_password_page.dart';
import 'package:vbvs_app/pages/mh_page/user_agreement_page.dart';
import 'package:vbvs_app/pages/sleep_report/new_sleep_report_page.dart'; import 'package:vbvs_app/pages/sleep_report/new_sleep_report_page.dart';
import '../pages/mh_page/bluetooth.dart'; import '../pages/mh_page/bluetooth.dart';
import '../pages/mh_page/edit_address_page.dart'; import '../pages/mh_page/edit_address_page.dart';
import '../pages/mh_page/message/messageDetail.dart';
import '../pages/mh_page/message_page.dart'; import '../pages/mh_page/message_page.dart';
import '../pages/mh_page/new_settingPage.dart'; import '../pages/mh_page/new_settingPage.dart';
@@ -49,6 +56,7 @@ ThemeController themeController = Get.find();
var mhroutes = { var mhroutes = {
"/mianPageBottomChange": (contxt) => MainPageBBottomChange(), "/mianPageBottomChange": (contxt) => MainPageBBottomChange(),
"/homePage": (context) => NewHomePage(),
"/homeDeviceType": (contxt) => HomeDeviceType(), "/homeDeviceType": (contxt) => HomeDeviceType(),
"/editUserInfoPage": (contxt) => EditUserPage(), "/editUserInfoPage": (contxt) => EditUserPage(),
"/peopleInfoPage": (contxt, {arguments}) => PeopleInfoPage( "/peopleInfoPage": (contxt, {arguments}) => PeopleInfoPage(
@@ -81,7 +89,8 @@ var mhroutes = {
"/findPasswordPage": (context) => FindPasswordPage(), "/findPasswordPage": (context) => FindPasswordPage(),
"/loginPage": (context) => MHTLoginPage(), "/loginPage": (context) => MHTLoginPage(),
"/updatePasswordPage": (context) => UpdatePasswordPage(), "/updatePasswordPage": (context) => UpdatePasswordPage(),
"/deviceSharePage": (context) => ShareDeviceWidget(), "/deviceSharePage": (context, {arguments}) =>
ShareDeviceWidget(data: arguments),
"/deviceListPage": (context) => DeviceListPage(), "/deviceListPage": (context) => DeviceListPage(),
"/mHTDeviceTypePage": (context, {arguments}) => MHTBindDeviceTypePage(), "/mHTDeviceTypePage": (context, {arguments}) => MHTBindDeviceTypePage(),
"/mHTBlueteethDevicePage": (context, {arguments}) => "/mHTBlueteethDevicePage": (context, {arguments}) =>
@@ -95,6 +104,12 @@ var mhroutes = {
"/helpArticle": (contxt, {arguments}) => HelpArticle(article: arguments), "/helpArticle": (contxt, {arguments}) => HelpArticle(article: arguments),
"/mHTPeopleInfoPage": (contxt) => MHTPeopleInfoPage(), "/mHTPeopleInfoPage": (contxt) => MHTPeopleInfoPage(),
"/applyRepairSuccess": (contxt) => ApplyRepairSuccess(), "/applyRepairSuccess": (contxt) => ApplyRepairSuccess(),
"/aboutUs": (contxt) => MhAboutUsPage(),
"/userAgreementPage": (context) => UserAgreementPage(),
"/privacyPolicyPage": (context) => PrivacyPolicyPage(),
"/shareDeviceDetail": (context) => ShareDeviceDetailWidget(),
"/messageDetail": (context, {arguments}) =>
MessageDetailPage(data: arguments),
}; };
var mhonGenerateRoute = (RouteSettings settings) { var mhonGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // 获取路由名称,如 /news 或 /search final String? name = settings.name; // 获取路由名称,如 /news 或 /search

View File

@@ -444,7 +444,11 @@ packages:
description: description:
path: "." path: "."
ref: main ref: main
<<<<<<< HEAD
resolved-ref: "840bcea66ee9222d9698a58f12a06107f337b59f" resolved-ref: "840bcea66ee9222d9698a58f12a06107f337b59f"
=======
resolved-ref: f307495aac440031d119a728beaccf5d33003932
>>>>>>> 13eb25e1c30dcd81c87aa85bcb5306ca0931ed21
url: "https://gitea.wslpc.real.he-info.cn:94/flutter/easydevice.git" url: "https://gitea.wslpc.real.he-info.cn:94/flutter/easydevice.git"
source: git source: git
version: "0.0.1" version: "0.0.1"
@@ -452,8 +456,13 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
<<<<<<< HEAD
ref: main ref: main
resolved-ref: "13a86afdcf71b55017ebf7ee2c22af211e642603" resolved-ref: "13a86afdcf71b55017ebf7ee2c22af211e642603"
=======
ref: e86d515f77
resolved-ref: e86d515f77a736a5e6f09036e5e022153cde425d
>>>>>>> 13eb25e1c30dcd81c87aa85bcb5306ca0931ed21
url: "https://gitea.wslpc.real.he-info.cn:94/flutter/easyweb.git" url: "https://gitea.wslpc.real.he-info.cn:94/flutter/easyweb.git"
source: git source: git
version: "0.0.1" version: "0.0.1"

View File

@@ -66,7 +66,7 @@ dependencies:
easyweb: easyweb:
git: git:
url: https://gitea.wslpc.real.he-info.cn:94/flutter/easyweb.git url: https://gitea.wslpc.real.he-info.cn:94/flutter/easyweb.git
ref: main ref: e86d515f77
archive: ^4.0.0 archive: ^4.0.0