更新棉花糖

This commit is contained in:
wyf
2025-06-16 09:32:24 +08:00
parent d8b46c41ad
commit acde8340a8
27 changed files with 6762 additions and 658 deletions

View File

@@ -0,0 +1,103 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
class HomeDeviceStausWidget extends StatefulWidget {
final deviceStatus;
const HomeDeviceStausWidget({super.key, required this.deviceStatus});
@override
State<HomeDeviceStausWidget> createState() => _HomeDeviceStausWidgetState();
}
class _HomeDeviceStausWidgetState extends State<HomeDeviceStausWidget> {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
constraints: BoxConstraints(minHeight: 180.rpx),
decoration: BoxDecoration(
color: Color(0xFF003058),
borderRadius: BorderRadius.circular(16.rpx),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(67.rpx, 0.rpx, 30.rpx, 0.rpx),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 170.rpx,
height: 81.rpx,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Image.network(
widget.deviceStatus['device_image'], // 从DeviceStatus获取图片
width: 200.rpx,
height: 200.rpx,
fit: BoxFit.cover,
),
),
),
Text(
'${(widget.deviceStatus['name'] ?? '').isEmpty ? '未命名'.tr : widget.deviceStatus['name']}',
style: TextStyle(
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0.0.rpx,
),
),
].divide(SizedBox(height: 26.rpx)),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Text(
// widget.deviceStatus['status'] == 1 ? '在线'.tr : '离线'.tr,
// style: TextStyle(
// color: widget.deviceStatus['status'] == 1
// ? stringToColor("#07BD60")
// : stringToColor("#F84B20"),
// fontSize: 26.rpx,
// letterSpacing: 0.0.rpx,
// ),
// ),
CustomCard(
gradientDirection: GradientDirection.vertical,
borderRadius: 10.rpx,
onTap: () {
// 点击回调逻辑放这里
},
colors:
AppConstants().mhtButtongradientColors, // 你原本没有渐变,单色即可
enableGradient: true, // 关闭渐变
enableAnimation: true, // 启用缩放动画
child: SizedBox(
width: 150.rpx,
height: 61.rpx,
child: Center(
child: Text(
'控制'.tr,
style: TextStyle(
color: Color(0xFF003058),
fontSize: 26.rpx,
letterSpacing: 0.0.rpx,
),
),
),
),
),
].divide(SizedBox(height: 36.rpx)),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/pages/mh_page/homepage/component/HomeDeviceStausWidget.dart';
class HomeDeviceWidget extends StatefulWidget {
final String roomName;
final List deviceStatusList;
const HomeDeviceWidget({
super.key,
required this.roomName,
required this.deviceStatusList,
});
@override
State<HomeDeviceWidget> createState() => _HomeDeviceWidgetState();
}
class _HomeDeviceWidgetState extends State<HomeDeviceWidget> {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(16.rpx, 0.rpx, 0.rpx, 35.rpx),
child: Text(
widget.roomName,
maxLines: 2,
style: TextStyle(
color: Color(0xFFFBFDFF),
fontSize: 30.rpx,
letterSpacing: 0.0.rpx,
),
),
),
Column(
mainAxisSize: MainAxisSize.max,
children: widget.deviceStatusList
.map((deviceStatus) => HomeDeviceStausWidget(deviceStatus: deviceStatus))
.toList()
.divide(SizedBox(height: 30.rpx)),
),
],
),
);
}
}

View File

@@ -0,0 +1,330 @@
import 'dart:convert';
import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:ef/ef.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/ServiceConstant.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/model/api_response.dart';
part 'mht_home_controller.g.dart'; // 由json_serializable自动生成的部分
@JsonSerializable()
class MHTHomeModel {
MHTHomeModel();
// 从JSON反序列化时的异常处理
factory MHTHomeModel.fromJson(Map<String, dynamic> json) {
try {
return _$MHTHomeModelFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return MHTHomeModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$MHTHomeModelToJson(this);
}
class MHTHomeController extends GetControllerEx<MHTHomeModel> {
MHTHomeController() {
attr = GetModel(MHTHomeModel()).obs;
}
RxInt bindDeviceNum = 0.obs; //设备数量
RxMap deviceList = {}.obs; //设备列表
RxMap<String, List<dynamic>> sleepReportData = <String, List<dynamic>>{}.obs;
RxString keyWord = "".obs;
String wifiMac = "";
Future<ApiResponse> getDeviceNum() async {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "设备.设备列表请求失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_list;
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?bindNum=1";
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 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) {
bindDeviceNum.value = res.total!;
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> getDeviceList(
{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) {
deviceList.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 {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_bind;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
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";
}
}
final data = {
"mac": device['mac'],
};
var response =
await EasyDartModule.dio.delete(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);
MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr);
if (res.code == HttpStatusCodes.ok) {
return res;
}
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
return apiResponse;
} catch (e) {
EasyDartModule.logger.info("解绑设备: $e");
DailyLogUtils.writeLog("解绑设备: $e");
} finally {
EasyDartModule.logger.info("用户操作:解绑设备");
DailyLogUtils.writeLog("用户操作:解绑设备");
}
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
Future<ApiResponse> getSleepReport() async {
try {
sleepReportData.value = {};
ApiResponse<Map<String, List<dynamic>>> apiResponse = ApiResponse(
code: -1,
msg: "请求失败".tr,
);
if (deviceList.value.isEmpty) {
return ApiResponse(
code: HttpStatusCodes.ok,
msg: "请求成功".tr,
);
}
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.sleep_report;
// for (var device in deviceList.value) {
// String mac = device['mac'] ?? "";
// if (mac.isEmpty) continue;
// sleepReportData[mac] = []; // 初始化当前设备的数据列表
// String queryUrl =
// "$serviceAddress$serviceName$serviceApi?mac=$mac&time=${DateTime.now().millisecondsSinceEpoch}";
// try {
// 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 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);
// if (res.code == HttpStatusCodes.ok && res.data != null) {
// // 确保数据是一个列表
// if (res.data is List) {
// sleepReportData[mac] = List.from(res.data);
// } else {
// sleepReportData[mac] = [res.data];
// }
// }
// }
// } catch (e) {
// EasyDartModule.logger.warning("请求设备 $mac 的睡眠数据失败: $e");
// }
// }
if (sleepReportData.value.isNotEmpty) {
// 遍历 Map 中的每一个键值对
sleepReportData.value.forEach((key, report) {
// 确保 report 列表不为空
if (report.isNotEmpty) {
// 获取该列表的最后一个元素
var lastElement = report.last;
// 给最后一个元素添加 selected 属性
lastElement['selected'] = true; // 假设每个元素是一个 Map 类型
}
});
}
updateAll();
return ApiResponse(
code: HttpStatusCodes.ok,
msg: "请求成功".tr,
data: sleepReportData,
);
} catch (e) {
EasyDartModule.logger.info("设备请求列表异常: $e");
DailyLogUtils.writeLog("设备请求列表异常: $e");
return ApiResponse(code: -1, msg: "未知错误".tr, data: {});
}
}
updateDeviceShow(device) async {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "操作失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_show;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
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 = {
"id": device['_id'],
"show": !device['show'],
};
var response =
await EasyDartModule.dio.put(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);
MyUtils.formatResponse(res, "操作成功".tr, "操作失败".tr);
if (res.code == HttpStatusCodes.ok) {
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
}
}

View File

@@ -0,0 +1,13 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'mht_home_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
MHTHomeModel _$MHTHomeModelFromJson(Map<String, dynamic> json) =>
MHTHomeModel();
Map<String, dynamic> _$MHTHomeModelToJson(MHTHomeModel instance) =>
<String, dynamic>{};

File diff suppressed because it is too large Load Diff