From 6ec1c79866fd9e3ec431c01b4a01c09502cba2db Mon Sep 17 00:00:00 2001 From: czz <862977248@qq.com> Date: Wed, 11 Jun 2025 08:47:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9ui=E8=AE=BE=E8=AE=A1=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/mipmap-ldpi/ic_launchermh.png | Bin 0 -> 1904 bytes assets/img/icon/address.svg | 1 + assets/img/icon/customer_service.svg | 1 + assets/img/icon/default_head.svg | 1 + assets/img/icon/help.svg | 1 + assets/img/icon/mall.svg | 1 + assets/img/icon/order.svg | 1 + assets/img/icon/plus.svg | 1 + assets/img/icon/repair.svg | 1 + assets/img/icon/store.svg | 1 + lib/common/util/CommonVariables.dart | 4 + .../mh_controller/book_info_controller.dart | 69 +- lib/controller/mh_controller/device.dart | 22 + lib/controller/mh_controller/device.g.dart | 23 + .../mh_controller/device_list_controller.dart | 100 +++ .../device_list_controller.g.dart | 20 + .../mh_controller/device_share.dart | 15 + .../mh_controller/device_share.g.dart | 22 + .../mhdevice_share_controller.dart | 122 ++++ .../mhdevice_share_controller.g.dart | 34 + lib/main.dart | 7 +- lib/pages/common/selectDialog.dart | 304 ++++++-- .../component/main_page_b_bottom_change.dart | 157 +--- lib/pages/mh_page/ShareUserWidget.dart | 177 +++++ lib/pages/mh_page/address_list_page.dart | 45 +- lib/pages/mh_page/bluetooth.dart | 8 +- lib/pages/mh_page/book_info_page.dart | 24 +- lib/pages/mh_page/device/device.dart | 439 ++++++++++++ lib/pages/mh_page/device_list.dart | 134 ++++ lib/pages/mh_page/device_share_page.dart | 672 ++++++++++++++++++ .../mh_page/experience_store_widget.dart | 1 - lib/pages/mh_page/new_mine_page.dart | 36 +- lib/pages/mh_page/people_info.dart | 8 +- lib/pages/mh_page/repair_history_widget.dart | 21 +- lib/pages/mh_page/searchWidget.dart | 39 +- lib/routers/mh_routers.dart | 38 +- 36 files changed, 2200 insertions(+), 350 deletions(-) create mode 100644 android/app/src/main/res/mipmap-ldpi/ic_launchermh.png create mode 100644 assets/img/icon/address.svg create mode 100644 assets/img/icon/customer_service.svg create mode 100644 assets/img/icon/default_head.svg create mode 100644 assets/img/icon/help.svg create mode 100644 assets/img/icon/mall.svg create mode 100644 assets/img/icon/order.svg create mode 100644 assets/img/icon/plus.svg create mode 100644 assets/img/icon/repair.svg create mode 100644 assets/img/icon/store.svg create mode 100644 lib/controller/mh_controller/device.dart create mode 100644 lib/controller/mh_controller/device.g.dart create mode 100644 lib/controller/mh_controller/device_list_controller.dart create mode 100644 lib/controller/mh_controller/device_list_controller.g.dart create mode 100644 lib/controller/mh_controller/device_share.dart create mode 100644 lib/controller/mh_controller/device_share.g.dart create mode 100644 lib/controller/mh_controller/mhdevice_share_controller.dart create mode 100644 lib/controller/mh_controller/mhdevice_share_controller.g.dart create mode 100644 lib/pages/mh_page/ShareUserWidget.dart create mode 100644 lib/pages/mh_page/device/device.dart create mode 100644 lib/pages/mh_page/device_list.dart create mode 100644 lib/pages/mh_page/device_share_page.dart diff --git a/android/app/src/main/res/mipmap-ldpi/ic_launchermh.png b/android/app/src/main/res/mipmap-ldpi/ic_launchermh.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d9fbc8877da5cf5a5b5a5a7ef159ac84f39e73 GIT binary patch literal 1904 zcmV-$2aouPP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x2I)yeK~z}7wU=FN6xS8UfA`Mp?5^!K1{~~QK2jS9C8#2S z3TmNB1d&7nB_froNT7&Fjnux7lm}4DOZyx_qDWDtR1nl8LRC`;)Z!(gZct>ZD&3G0 z*@_D`Q38e3Hul=Pu=8Zs< z`6MF(j-yz;x)H4vK_G;oA&P`3f+!M1oL*y++uf39=0!~P=;~_3aa4(j6=|m+A{Y~F ziz0uQ#u|8DhFu6cI#Q%k8e=MA?6LJ!MI8GyHk;;25Tw(ZB}4?nrSzO>RLw9{Jp1G*L%mssdb2$HRZ zqCh}9f{8Sre~_gwn*pHvu}L1@@fcbgj8SaZ&`cN_zz~K~O7pn>STXUrG4^wAgpB4N zfBqLg`{^xAq*>clpmkx$8}GF9#=GsbE(}@QRlpd{&-YI7?$Li!^wkVP_FT$7tDbWb z1aR?EhTrV}3Q(+HQ$Q)<@?Zm(KW{)OVf~r{0Kfg^2%q$)r}?EKAogIjw?yVh2qpaC z^aG?*hRziQ)~zb=^=N`((WO{)`Fb?Lx>W@_R}^Sybb0@Sg*aO3dS*JIn4&uuJ+32U zKWoAd6uY+F=J74Ll7H+Y_kEJ#@huZfRN(*9UErc_|HYY(!SyP|vY30|y zxQ?TRUmaNi$_o1ZAKN(dy8+g%{VzR#U54)~60Vu05LSz;(3(@00fZqKqu8-^oUd*s z8Mx92l!_0UhdU?PyvgJ5pDqF-klO63&ZsD&d>s31PJ{p)2a-uc(bp` zCqYwrhac|#0b18aTLhY#T$Z#okehOFbX4P+_?l8DTSLd5--95fAdwIThf|no?h^w` z+LBBb6S$5kdE}c5p@=GdZ$D=UvSzd8ewq|Oqjh`(`@7b*lvx4>MS{s(KoHpMQc7Wr z5Cn!|(UiJF+d(>xDrIhkQXN5t7hYJ&fdgGQj%@@yPxIo7mw4uxc3yt@Q$X?Ihd*X) z%xCxRivS!yzKQ+&FVoYrnUCvgHD~T!>P(jmT!lIe)&JBS)_C$Rin2Db2=>Ev#SPLMG$##1jv2@Zc)0 zU%$(tL;a=jDn>?p4jo!eHapInZ+?N+md@?l0mcX=z_ZsO-wzlV*umn(9{GHP2uw}} zJoVH?4j*1afBzI69Vtdee3mayGdMWK%9Ra_j{4lZd6&1}-pI9U1riBM;=T87Ff>%) z=+X6DyH-GJh$49HwX3}T`Vgs?&Nen|Sip17ea!REFK5}ZG_SmJ1*I&ZTrS|sl{_m}q)8?vG*4jxCOLV3ZMGM#b=RJHfLNsm7?_Y3ZajHy&_s^z=%LSv8i{p|wHd%+#PS2|5i&a@45_Kq;76w|Tca)+ULukUXc4dDA* zZ$R_bdm$xaQ$OA`>yfDzHj|Fq3(Z@thN{;f`$cj)@HB7=xCyoWSG}=dfs5m)npd5f qWGVtg5PNTRN-3U(5vo{@c`}s0000 \ No newline at end of file diff --git a/assets/img/icon/customer_service.svg b/assets/img/icon/customer_service.svg new file mode 100644 index 0000000..c319519 --- /dev/null +++ b/assets/img/icon/customer_service.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/default_head.svg b/assets/img/icon/default_head.svg new file mode 100644 index 0000000..144d11c --- /dev/null +++ b/assets/img/icon/default_head.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/help.svg b/assets/img/icon/help.svg new file mode 100644 index 0000000..0cd85bd --- /dev/null +++ b/assets/img/icon/help.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/mall.svg b/assets/img/icon/mall.svg new file mode 100644 index 0000000..bccbfd6 --- /dev/null +++ b/assets/img/icon/mall.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/order.svg b/assets/img/icon/order.svg new file mode 100644 index 0000000..d888ded --- /dev/null +++ b/assets/img/icon/order.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/plus.svg b/assets/img/icon/plus.svg new file mode 100644 index 0000000..1697545 --- /dev/null +++ b/assets/img/icon/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/repair.svg b/assets/img/icon/repair.svg new file mode 100644 index 0000000..efb83e1 --- /dev/null +++ b/assets/img/icon/repair.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/store.svg b/assets/img/icon/store.svg new file mode 100644 index 0000000..fe777a3 --- /dev/null +++ b/assets/img/icon/store.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/common/util/CommonVariables.dart b/lib/common/util/CommonVariables.dart index 5732723..cc0bc68 100644 --- a/lib/common/util/CommonVariables.dart +++ b/lib/common/util/CommonVariables.dart @@ -11,9 +11,13 @@ class CommonVariables { static String enterpriseName = "合肥眠花糖家具有限责任公司"; //备案时间 static String ICPTime = "2022-2025"; + static String shoph5Url = "https://zhmht.swes.com.cn:1443"; static Map callMap = {}; static const String weather_apiKey = '40e23445cf0a29561af2b5b7d506a38b'; // 替换为你的 API 密钥 + static String shareText = "您的朋友邀请您使用《智慧眠花糖》APP,请复制后面链接在浏览器中打开! " + + shoph5Url + + "/#/pages/download/download"; } diff --git a/lib/controller/mh_controller/book_info_controller.dart b/lib/controller/mh_controller/book_info_controller.dart index 4b4420d..e873978 100644 --- a/lib/controller/mh_controller/book_info_controller.dart +++ b/lib/controller/mh_controller/book_info_controller.dart @@ -1,7 +1,14 @@ import 'dart:convert'; +import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:ef/ef.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/common/util/requestWithLog.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; +import 'package:vbvs_app/model/api_response.dart'; class BookInfoModel { // DateTime? dateTime; //预约时间 @@ -16,6 +23,14 @@ class BookInfoModel { Map dataT = {}; BookInfoModel(); + BookInfoModel.fromJson(Map json) { + // dateTime = json['dateTime']; + userName = json['userName']; + userPhone = json['userPhone']; + time_period = json['time_period']; + // select_time = json['select_time']; + select_time_index = json['select_time_index']; + } } class BookInfoController extends GetControllerEx { @@ -25,13 +40,44 @@ class BookInfoController extends GetControllerEx { // get userInfoController => Get.find(); + Future getData(String storeId) async { + // 初始化模型 + model.datetimes = []; + model.datetimes_index = null; + model.dataT = {}; + updateAll(); + + String url = + "https://crm-api.swes.com.cn/agent/userBook/config/detailConfigByStore?storeId=$storeId"; + + await requestWithLog( + logTitle: "获取预约门店时间", + method: MyHttpMethod.get, + queryUrl: url, + successMsg: "获取预约门店时间成功", + errorMsg: "获取预约门店时间失败", + onSuccess: (res) { + final data = res.data; + if (data != null) { + model.datetimes = data["dateList"] ?? []; + model.datetimes_index = 0; + model.dataT = data; + time_periodChange(); // 原来的 time_periodChange + updateAll(); + } + }, + onFailure: (res) {}, + ); + } + // getData(id) { // model.datetimes = []; // model.datetimes_index = null; // model.dataT = {}; // updateAll(); - // ApiService.reservation.get("/agent/userBook/config/detailConfigByStore?storeId=$id") - // .then((d) { + // ApiService.reservation + // .get("/agent/userBook/config/detailConfigByStore?storeId=$id") + // .then((d) { // model.datetimes = d.data["dateList"]; // model.datetimes_index = 0; // model.dataT = d.data; @@ -39,14 +85,15 @@ class BookInfoController extends GetControllerEx { // }); // } - // time_periodChange() { - // if(model.datetimes_index == null) { - // return; - // } - // model.select_time_index = null; - // model.time_period = model.dataT[model.datetimes?[model.datetimes_index!]["day"]]; - // updateAll(); - // } + time_periodChange() { + if (model.datetimes_index == null) { + return; + } + model.select_time_index = null; + model.time_period = + model.dataT[model.datetimes?[model.datetimes_index!]["day"]]; + updateAll(); + } // submitData(id) { // String tel = userInfoController.model?.user?.tel ?? ""; diff --git a/lib/controller/mh_controller/device.dart b/lib/controller/mh_controller/device.dart new file mode 100644 index 0000000..a35f170 --- /dev/null +++ b/lib/controller/mh_controller/device.dart @@ -0,0 +1,22 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'device_share.dart'; + +part 'device.g.dart'; + +@JsonSerializable() +class DeviceModel { + String? name; //设备名称 + String? id; //设备id + String? status; //设备状态 + String? roomName; //设备所属房间 + String? shareNum; //设备已分享数量 + + @JsonKey(ignore: true) + List shareInfo = []; //设备分享信息 + + DeviceModel(); + static DeviceModel fromJson(Map json) => + _$DeviceModelFromJson(json); + Map toJson() => _$DeviceModelToJson(this); +} diff --git a/lib/controller/mh_controller/device.g.dart b/lib/controller/mh_controller/device.g.dart new file mode 100644 index 0000000..a1cb4ec --- /dev/null +++ b/lib/controller/mh_controller/device.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'device.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DeviceModel _$DeviceModelFromJson(Map json) => DeviceModel() + ..name = json['name'] as String? + ..id = json['id'] as String? + ..status = json['status'] as String? + ..roomName = json['roomName'] as String? + ..shareNum = json['shareNum'] as String?; + +Map _$DeviceModelToJson(DeviceModel instance) => + { + 'name': instance.name, + 'id': instance.id, + 'status': instance.status, + 'roomName': instance.roomName, + 'shareNum': instance.shareNum, + }; diff --git a/lib/controller/mh_controller/device_list_controller.dart b/lib/controller/mh_controller/device_list_controller.dart new file mode 100644 index 0000000..a10ba00 --- /dev/null +++ b/lib/controller/mh_controller/device_list_controller.dart @@ -0,0 +1,100 @@ +import 'dart:convert'; +import 'dart:ui'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:ef/ef.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/controller/mh_controller/device.dart'; +import 'package:vbvs_app/model/api_response.dart'; + +part 'device_list_controller.g.dart'; + +@JsonSerializable() +class DeviceListModel { + //设备列表 + List deviceList = []; + List deviceListWyf = []; + + @JsonKey(ignore: true) + String? keyword; + @JsonKey(ignore: true) + Color? color = Color(0xFFFFFFFF); + + DeviceListModel(); + static DeviceListModel fromJson(Map json) => + _$DeviceListModelFromJson(json); + Map toJson() => _$DeviceListModelToJson(this); +} + +class DeviceListController extends GetControllerEx { + DeviceListController() { + attr = GetModel(DeviceListModel()).obs; + } + + // @override + // void onInit() { + // super.onInit(); + // model.keyword = ""; + // getDeviceList(); // 正确的初始化数据调用 + // } + + // getDeviceList({int time = 1}) async { + // String search = (model.keyword != null && model.keyword!.isNotEmpty) + // ? "?key=${model.keyword}" + // : ""; + // var data = await ApiService.request.get("/api/device/info/list$search"); + // if (data.data["data"] != null) { + // try { + // List tmp = data.data["data"] as List; + // model.deviceList = tmp.map((obj) => DeviceModel.fromJson(obj)).toList(); + // model.deviceListWyf = tmp; + // } catch (e) { + // print(e); + // } + // } else { + // model.deviceList = []; + // model.deviceListWyf = []; + // } + // updateAll(); + // } + + getDeviceList() async { + try { + String search = (model.keyword != null && model.keyword!.isNotEmpty) + ? "?key=${model.keyword}" + : ""; + 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}$search"; + 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!; + model.deviceList =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 + } +} diff --git a/lib/controller/mh_controller/device_list_controller.g.dart b/lib/controller/mh_controller/device_list_controller.g.dart new file mode 100644 index 0000000..1d4a7b4 --- /dev/null +++ b/lib/controller/mh_controller/device_list_controller.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'device_list_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DeviceListModel _$DeviceListModelFromJson(Map json) => + DeviceListModel() + ..deviceList = (json['deviceList'] as List) + .map((e) => DeviceModel.fromJson(e as Map)) + .toList() + ..deviceListWyf = json['deviceListWyf'] as List; + +Map _$DeviceListModelToJson(DeviceListModel instance) => + { + 'deviceList': instance.deviceList, + 'deviceListWyf': instance.deviceListWyf, + }; diff --git a/lib/controller/mh_controller/device_share.dart b/lib/controller/mh_controller/device_share.dart new file mode 100644 index 0000000..0dcf329 --- /dev/null +++ b/lib/controller/mh_controller/device_share.dart @@ -0,0 +1,15 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'device_share.g.dart'; + +@JsonSerializable() +class DeviceShareModel { + String? name; //设备名称 + String? phone; //被分享手机号 + DateTime? share_time; //分享时间 + + DeviceShareModel(); + static DeviceShareModel fromJson(Map json) => + _$DeviceShareModelFromJson(json); + Map toJson() => _$DeviceShareModelToJson(this); +} diff --git a/lib/controller/mh_controller/device_share.g.dart b/lib/controller/mh_controller/device_share.g.dart new file mode 100644 index 0000000..0cde0f9 --- /dev/null +++ b/lib/controller/mh_controller/device_share.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'device_share.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DeviceShareModel _$DeviceShareModelFromJson(Map json) => + DeviceShareModel() + ..name = json['name'] as String? + ..phone = json['phone'] as String? + ..share_time = json['share_time'] == null + ? null + : DateTime.parse(json['share_time'] as String); + +Map _$DeviceShareModelToJson(DeviceShareModel instance) => + { + 'name': instance.name, + 'phone': instance.phone, + 'share_time': instance.share_time?.toIso8601String(), + }; diff --git a/lib/controller/mh_controller/mhdevice_share_controller.dart b/lib/controller/mh_controller/mhdevice_share_controller.dart new file mode 100644 index 0000000..0dd2c41 --- /dev/null +++ b/lib/controller/mh_controller/mhdevice_share_controller.dart @@ -0,0 +1,122 @@ +import 'package:dio/dio.dart'; +import 'package:dio/src/form_data.dart' as formdata; +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; + +part 'mhdevice_share_controller.g.dart'; + +@JsonSerializable() +class MHDeviceShareModel { + String? phone; + int? type = 1; + + String? msg; + int? show = 0; + + int limit = AppConstants.limit; + int offset = 0; + bool isLoading = false; + bool hasMore = true; + + // List? shareUser = [ + // {"type": 1}, + // {"type": 2} + // ]; + List? shareUser = []; + Map mainShare = {}; + + MHDeviceShareModel(); + static MHDeviceShareModel fromJson(Map json) => + _$MHDeviceShareModelFromJson(json); + Map toJson() => _$MHDeviceShareModelToJson(this); +} + +class MHDeviceShareController extends GetControllerEx { + MHDeviceShareController() { + attr = GetModel(MHDeviceShareModel()).obs; + } + + @override + void onInit() { + super.onInit(); + model.shareUser = [ + { + 'userName': '张三', + 'opType': 1, // 允许控制 + }, + { + 'userName': '李四', + 'opType': 2, // 仅查看 + }, + { + 'userName': '王五', + 'opType': 1, + }, + ]; + update(); // 刷新UI + } + + // Future sendInvite(String? phone, String mac) async { + // if (phone == null || phone.isEmpty) { + // return "手机号不能为空"; + // } + // if (!MyUtils.isValidPhoneNumber(phone)) { + // return "手机号格式不正确"; + // } + // var type = model.type; + // try { + // var aa = await ApiService.requestNoInfo.post("/api/device/info/share", + // data: formdata.FormData.fromMap( + // {"mac": mac, "tel": phone, "type": type})); + // return ""; + // } catch (e) { + // if (e is DioError) { + // // 返回 DioError 的 message 属性 + // return e.message!; + // } else { + // // 处理其他类型的错误 + // return e.toString(); + // } + // } + // } + + // Future initData() async { + // //todo 请求分享列表 + // var deviceController = Get.find(); + // var query = { + // "mac": deviceController.model.deviceMain['mac'], + // }; + // var data = await ApiService.request + // .get("/api/device/info/share", data: formdata.FormData.fromMap(query)); + + // if (data.data["data"] != null) { + // try { + // List tmp = data.data["data"] as List; + // model.shareUser = tmp; + // } catch (e) { + // print(e); + // } + // } else { + // model.shareUser = []; + // } + // updateAll(); + // } + + // //保存 + // saveShareDevice(Map shareInfo, RxInt type) async { + // return await ApiService.request.put("/api/device/info/share", + // data: formdata.FormData.fromMap({ + // "mac": shareInfo['mac'], + // "tel": shareInfo['tel'], + // "type": type.value + // })); + // } + + // //删除 + // deleteShare(Map shareInfo) async { + // return await ApiService.request.delete("/api/device/info/share", + // data: formdata.FormData.fromMap( + // {"mac": shareInfo['mac'], "tel": shareInfo['tel']})); + // } +} diff --git a/lib/controller/mh_controller/mhdevice_share_controller.g.dart b/lib/controller/mh_controller/mhdevice_share_controller.g.dart new file mode 100644 index 0000000..454795c --- /dev/null +++ b/lib/controller/mh_controller/mhdevice_share_controller.g.dart @@ -0,0 +1,34 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mhdevice_share_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MHDeviceShareModel _$MHDeviceShareModelFromJson(Map json) => + MHDeviceShareModel() + ..phone = json['phone'] as String? + ..type = (json['type'] as num?)?.toInt() + ..msg = json['msg'] as String? + ..show = (json['show'] as num?)?.toInt() + ..limit = (json['limit'] as num).toInt() + ..offset = (json['offset'] as num).toInt() + ..isLoading = json['isLoading'] as bool + ..hasMore = json['hasMore'] as bool + ..shareUser = json['shareUser'] as List? + ..mainShare = json['mainShare'] as Map; + +Map _$MHDeviceShareModelToJson(MHDeviceShareModel instance) => + { + 'phone': instance.phone, + 'type': instance.type, + 'msg': instance.msg, + 'show': instance.show, + 'limit': instance.limit, + 'offset': instance.offset, + 'isLoading': instance.isLoading, + 'hasMore': instance.hasMore, + 'shareUser': instance.shareUser, + 'mainShare': instance.mainShare, + }; diff --git a/lib/main.dart b/lib/main.dart index 9500229..f63526a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -36,12 +36,14 @@ import 'package:vbvs_app/controller/message/message_setting_controller.dart'; import 'package:vbvs_app/controller/mh_controller/address_controller.dart'; import 'package:vbvs_app/controller/mh_controller/address_list_controller.dart'; import 'package:vbvs_app/controller/mh_controller/book_info_controller.dart'; +import 'package:vbvs_app/controller/mh_controller/device_list_controller.dart'; import 'package:vbvs_app/controller/mh_controller/experience_store_list_page.dart'; import 'package:vbvs_app/controller/mh_controller/find_password_controller.dart'; import 'package:vbvs_app/controller/mh_controller/issue_controller.dart'; import 'package:vbvs_app/controller/mh_controller/issue_preview_controller.dart'; import 'package:vbvs_app/controller/mh_controller/message_controller.dart'; import 'package:vbvs_app/controller/mh_controller/mh_language_controller.dart'; +import 'package:vbvs_app/controller/mh_controller/mhdevice_share_controller.dart'; import 'package:vbvs_app/controller/mh_controller/my_experience_list_controller.dart'; import 'package:vbvs_app/controller/mh_controller/people_info_controller.dart'; import 'package:vbvs_app/controller/mh_controller/register_controller.dart'; @@ -79,7 +81,7 @@ Future main() async { // final selectapp = "th"; final selectapp = "mht"; // await AppLanguage().loadLanguage("en_US"); - await AppLanguage().loadLanguage("zh_CN",project: selectapp); + await AppLanguage().loadLanguage("zh_CN", project: selectapp); await initLanguageSetting(); WidgetsFlutterBinding.ensureInitialized(); @@ -274,6 +276,7 @@ Future dealBindProcess() async { } final GlobalKey navigatorKey = GlobalKey(); + class MyApp extends StatelessWidget { MyApp({super.key}); final ThemeController themeController = Get.put(ThemeController()); @@ -320,6 +323,7 @@ class MyApp extends StatelessWidget { Get.lazyPut(() => DeviceTypeController()), Get.lazyPut(() => BodyDeviceController()), Get.lazyPut(() => HomeController()), + Get.lazyPut(() => MHDeviceShareController()), Get.lazyPut(() => DeviceShareController()), Get.lazyPut(() => DeviceShareListController()), Get.lazyPut(() => DeviceCalibrationController()), @@ -329,6 +333,7 @@ class MyApp extends StatelessWidget { Get.lazyPut(() => WeatherModelController()), Get.lazyPut(() => RegisterController()), Get.lazyPut(() => UpdatePasswordController()), + Get.lazyPut(() => DeviceListController()), ])); } diff --git a/lib/pages/common/selectDialog.dart b/lib/pages/common/selectDialog.dart index ecbd95f..805682a 100644 --- a/lib/pages/common/selectDialog.dart +++ b/lib/pages/common/selectDialog.dart @@ -532,15 +532,156 @@ Future showHeightPickerDialog( ); } -Future showDayTimeSelectionDialog(BuildContext context, - {required List dayTimeArr, Function? checkChange, String title = ""}) { +// Future showDayTimeSelectionDialog(BuildContext context, +// {required List dayTimeArr, Function? checkChange, String title = ""}) { +// ThemeController themeController = Get.find(); + +// final hours = List.generate(24, (i) => i); +// final minutes = List.generate(60, (i) => i); + +// final RxInt hoursIndex = RxInt(hours.indexOf(dayTimeArr[0])); +// final RxInt minutesIndex = RxInt(minutes.indexOf(dayTimeArr[1])); + +// return showDialog( +// context: context, +// barrierDismissible: true, +// builder: (BuildContext context) { +// return Stack( +// children: [ +// Positioned( +// bottom: 0, +// left: 0, +// right: 0, +// child: Material( +// color: Colors.transparent, +// child: Dialog( +// backgroundColor: stringToColor("#182B7C"), +// insetPadding: EdgeInsets.zero, +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(0), +// ), +// child: Container( +// width: double.infinity, +// padding: EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, 90.rpx), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Text( +// title, +// style: FlutterFlowTheme.of(context) +// .bodyMedium +// .override( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// fontSize: 30.rpx, +// ), +// ), +// closeIconWhite, +// ], +// ), +// Container( +// height: 240.rpx, +// margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx), +// padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), +// child: Row( +// children: [ +// Expanded( +// child: Padding( +// padding: +// EdgeInsets.symmetric(horizontal: 10.rpx), +// child: getOnePickers(context, hours, hoursIndex, +// unit: ''), +// ), +// ), +// Text( +// "时", +// style: FlutterFlowTheme.of(context) +// .bodyMedium +// .override( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// fontSize: 30.rpx, +// ), +// ), +// Expanded( +// child: Padding( +// padding: +// EdgeInsets.symmetric(horizontal: 10.rpx), +// child: getOnePickers( +// context, minutes, minutesIndex, +// unit: ''), +// ), +// ), +// Text( +// "分", +// style: FlutterFlowTheme.of(context) +// .bodyMedium +// .override( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// fontSize: 30.rpx, +// ), +// ), +// ], +// ), +// ), +// InkWell( +// onTap: () { +// checkChange?.call([ +// hours[hoursIndex.value], +// minutes[minutesIndex.value] +// ]); +// Get.back(); +// }, +// child: Container( +// height: 68.rpx, +// alignment: Alignment.center, +// decoration: BoxDecoration( +// color: stringToColor("#D3B684"), +// borderRadius: BorderRadius.circular(10.rpx), +// ), +// child: Text( +// "确定", +// style: FlutterFlowTheme.of(context) +// .bodyMedium +// .override( +// fontFamily: 'Readex Pro', +// color: themeController.currentColor.sc3, +// fontSize: 30.rpx, +// ), +// ), +// ), +// ) +// ], +// ), +// ), +// ), +// ), +// ), +// ], +// ); +// }, +// ); +// } + +Future showDayTimeSelectionDialog( + BuildContext context, { + required List dayTimeArr, + Function(List)? checkChange, + String title = "选择时间", +}) { ThemeController themeController = Get.find(); + Color checkColor = stringToColor("#D3B684"); - final hours = List.generate(24, (i) => i); - final minutes = List.generate(60, (i) => i); + final List hours = List.generate(24, (i) => i); + final List minutes = List.generate(60, (i) => i); - final RxInt hoursIndex = RxInt(hours.indexOf(dayTimeArr[0])); - final RxInt minutesIndex = RxInt(minutes.indexOf(dayTimeArr[1])); + final RxInt hoursIndex = hours.indexOf(dayTimeArr[0]).obs; + final RxInt minutesIndex = minutes.indexOf(dayTimeArr[1]).obs; return showDialog( context: context, @@ -555,7 +696,7 @@ Future showDayTimeSelectionDialog(BuildContext context, child: Material( color: Colors.transparent, child: Dialog( - backgroundColor: stringToColor("#182B7C"), + backgroundColor: const Color(0xFF003058), insetPadding: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0), @@ -567,9 +708,24 @@ Future showDayTimeSelectionDialog(BuildContext context, mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ + // 顶部栏:取消 - 标题 - 确认 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.zero, + onTap: () => Navigator.of(context).pop(), + child: Container( + width: 100.rpx, + height: 60.rpx, + alignment: Alignment.center, + child: Text("取消", + style: TextStyle( + fontSize: 30.rpx, color: Colors.white)), + ), + ), Text( title, style: FlutterFlowTheme.of(context) @@ -580,82 +736,74 @@ Future showDayTimeSelectionDialog(BuildContext context, fontSize: 30.rpx, ), ), - closeIconWhite, + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.zero, + onTap: () { + checkChange?.call([ + hours[hoursIndex.value], + minutes[minutesIndex.value], + ]); + Get.back(); + }, + child: Container( + width: 100.rpx, + height: 60.rpx, + alignment: Alignment.center, + child: Text("确认", + style: TextStyle( + fontSize: 30.rpx, color: Colors.white)), + ), + ), ], ), - Container( - height: 240.rpx, - margin: EdgeInsets.only(top: 60.rpx, bottom: 60.rpx), - padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), - child: Row( - children: [ - Expanded( - child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.rpx), - child: getOnePickers(context, hours, hoursIndex, - unit: ''), - ), - ), - Text( - "时", - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: 'Readex Pro', - color: themeController.currentColor.sc3, - fontSize: 30.rpx, + SizedBox(height: 20.rpx), + Stack( + children: [ + Positioned.fill( + child: IgnorePointer( + child: Center( + child: Container( + height: 90.rpx, + margin: + EdgeInsets.symmetric(horizontal: 95.rpx), + decoration: BoxDecoration( + color: const Color(0xFF84F5FF), + borderRadius: BorderRadius.circular(16.rpx), ), - ), - Expanded( - child: Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.rpx), - child: getOnePickers( - context, minutes, minutesIndex, - unit: ''), - ), - ), - Text( - "分", - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: 'Readex Pro', - color: themeController.currentColor.sc3, - fontSize: 30.rpx, - ), - ), - ], - ), - ), - InkWell( - onTap: () { - checkChange?.call([ - hours[hoursIndex.value], - minutes[minutesIndex.value] - ]); - Get.back(); - }, - child: Container( - height: 68.rpx, - alignment: Alignment.center, - decoration: BoxDecoration( - color: stringToColor("#D3B684"), - borderRadius: BorderRadius.circular(10.rpx), - ), - child: Text( - "确定", - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: 'Readex Pro', - color: themeController.currentColor.sc3, - fontSize: 30.rpx, ), + ), + ), ), - ), - ) + SizedBox( + height: 240.rpx, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 95.rpx), + child: Row( + children: [ + Expanded( + child: getOnePickers( + context, + hours, + hoursIndex, + unit: "时", + ), + ), + Expanded( + child: getOnePickers( + context, + minutes, + minutesIndex, + unit: "分", + ), + ), + ], + ), + ), + ), + ], + ), ], ), ), diff --git a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart index 8d9596d..14527a2 100644 --- a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart +++ b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart @@ -1,160 +1,9 @@ -// import 'dart:io'; -// import 'package:flutter/material.dart'; -// import 'package:flutter/services.dart'; -// import 'package:get/get.dart'; -// import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; -// import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; -// import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; -// import 'package:vbvs_app/controller/message/message_controller.dart'; -// import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; -// import 'package:vbvs_app/controller/user_info_controller.dart'; -// import 'package:vbvs_app/enum/LoginStatus.dart'; -// import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; -// import 'package:vbvs_app/pages/main_bottom/e_page.dart'; -// import 'package:vbvs_app/pages/main_bottom/home_page.dart'; -// import 'package:vbvs_app/pages/main_bottom/message_page.dart'; -// import 'package:vbvs_app/pages/main_bottom/mine_page.dart'; -// class MainPageBBottomChange extends StatefulWidget { -// const MainPageBBottomChange({super.key}); - -// @override -// State createState() => _MainPageBottomChangeState(); -// } - -// class _MainPageBottomChangeState extends State -// with SingleTickerProviderStateMixin { -// final GlobalController globalController = Get.find(); -// final ThemeController themeController = Get.find(); -// final MessageController messageController = Get.find(); -// final MainPageController controller = Get.find(); -// final UserInfoController userInfoController = Get.find(); - -// late AnimationController _animationController; -// late Animation _positionAnimation; - -// final List pages = [ -// const HomePage(), -// const EPage(), -// const MessagePage(), -// const MinePage(), -// ]; - -// final List titles = ['首页', '报告', '控制', '我的']; -// final List icons = [ -// Icons.home, -// Icons.android, -// Icons.message, -// Icons.person, -// ]; - -// int selectedIndex = 0; -// double currentPosition = 0.0; - -// DateTime? _lastBackPressedTime; - -// @override -// void initState() { -// super.initState(); -// selectedIndex = controller.model.currentIndex; -// currentPosition = selectedIndex.toDouble(); - -// _animationController = AnimationController( -// vsync: this, -// duration: const Duration(milliseconds: 300), -// ); - -// _positionAnimation = Tween( -// begin: currentPosition, -// end: currentPosition, -// ).animate(CurvedAnimation( -// parent: _animationController, -// curve: Curves.easeOut, -// )) -// ..addListener(() { -// setState(() {}); -// }); -// } - -// void _onTabTapped(int index) { -// bool isLoggedIn = userInfoController.model.login == LoginStatus.LOGIN.code; - -// if ((index == 1 || index == 2) && !isLoggedIn) { -// TopSlideNotification.show(context, text: "必须登录提示".tr); -// Future.delayed(const Duration(milliseconds: 100), () { -// Get.toNamed("/loginPage"); -// }); -// return; -// } - -// if (selectedIndex != index) { -// final begin = currentPosition; -// final end = index.toDouble(); -// _positionAnimation = Tween(begin: begin, end: end).animate( -// CurvedAnimation(parent: _animationController, curve: Curves.easeOut), -// )..addListener(() { -// setState(() {}); -// }); - -// _animationController.forward(from: 0.0); -// currentPosition = end; -// selectedIndex = index; - -// controller.model.currentIndex = index; -// controller.updateAll(); -// } -// } - -// @override -// void dispose() { -// _animationController.dispose(); -// super.dispose(); -// } - -// Future _handleBackPressed() async { -// final now = DateTime.now(); -// if (_lastBackPressedTime == null || -// now.difference(_lastBackPressedTime!) > const Duration(seconds: 2)) { -// _lastBackPressedTime = now; -// TopSlideNotification.show(context, text: "滑动退出提醒".tr); -// return false; -// } -// return true; -// } - -// @override -// Widget build(BuildContext context) { -// return PopScope( -// canPop: false, -// onPopInvokedWithResult: (disposition, result) async { -// if (Platform.isAndroid) { -// final exit = await _handleBackPressed(); -// if (exit) SystemNavigator.pop(); -// } -// }, -// child: Obx(() { -// final hideBar = globalController.model.hideBottomNavigationBar; -// return Scaffold( -// backgroundColor: Colors.transparent, -// body: pages[controller.model.currentIndex], -// bottomNavigationBar: hideBar -// ? null -// : BezierBottomNavigationBar( -// selectedIndex: selectedIndex, -// animatedPosition: _positionAnimation.value, -// icons: icons, -// titles: titles, -// onTap: _onTabTapped, -// ), -// ); -// }), -// ); -// } -// } import 'package:flutter/material.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/homepage/new_Home_page.dart'; +import 'package:vbvs_app/pages/mh_page/device_list.dart'; import 'package:vbvs_app/pages/mh_page/new_mine_page.dart'; import 'package:vbvs_app/pages/mh_page/user/page/register_page.dart'; @@ -182,7 +31,9 @@ class _HomePageState extends State NewHomePage(), // PeopleInfoPage(), // Text('报告'), - RegisterPage(), + // RegisterPage(), + // ShareDeviceWidget(), + DeviceListPage(), // FindPasswordPage(), // Smys(), MattressControlPage(), diff --git a/lib/pages/mh_page/ShareUserWidget.dart b/lib/pages/mh_page/ShareUserWidget.dart new file mode 100644 index 0000000..a19ea34 --- /dev/null +++ b/lib/pages/mh_page/ShareUserWidget.dart @@ -0,0 +1,177 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; + +import 'package:vbvs_app/controller/mh_controller/mhdevice_share_controller.dart'; + +class ShareUserWidget extends GetView { + int index; + MHDeviceShareController repairListController; + + ShareUserWidget({required this.index, required this.repairListController}) {} + + @override + Widget build(BuildContext context) { + var info = repairListController.model.shareUser![index]; + return InkWell( + onTap: () { + repairListController.model.mainShare = + repairListController.model.shareUser![index]; + Get.toNamed('/share_device_user_detail'); + }, + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.073, + constraints: const BoxConstraints( + minHeight: 71, + ), + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: Color(0xFF929699), // 设置底部线条颜色 + width: 0, // 设置线条宽度 + ), + top: BorderSide( + color: Color(0xFF929699), // 设置底部线条颜色 + width: 0, // 设置线条宽度 + )), + ), + child: Padding( + padding: + EdgeInsetsDirectional.fromSTEB(37.rpx, 29.rpx, 42.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: 42.rpx, + height: 42.rpx, + child: SvgPicture.asset('assets/img/icon/default_head.svg'), + ), + + Expanded( + child: Container( + margin: + EdgeInsetsDirectional.only(start: 30.rpx, end: 30.rpx), + // width: MediaQuery.sizeOf(context).width * 0.5, + // height: MediaQuery.sizeOf(context).height * 0.075, + + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Align( + alignment: const AlignmentDirectional(-1, 0), + child: Text( + '${info['userName']}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0.0, + ), + ), + ), + ), + Expanded( + child: Align( + alignment: const AlignmentDirectional(-1, 0), + child: Text( + info['opType'] == 1 + ? '允许对方控制该设备' + : info['opType'] == 2 + ? '仅允许对方查看该设备' + : '', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFFC8CBD2), + fontSize: 20.rpx, + letterSpacing: 0.0, + ), + ), + ), + ), + ].divide(const SizedBox(height: 5)), + ), + ), + ), + // Container( + // width: MediaQuery.sizeOf(context).width * 0.2, + // height: MediaQuery.sizeOf(context).height * 0.075, + // constraints: const BoxConstraints( + // maxWidth: 130, + // ), + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context).secondaryBackground, + // ), + // child: Row( + // mainAxisSize: MainAxisSize.max, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Align( + // alignment: const AlignmentDirectional(0, 0), + // child: Text( + // ' ', + // style: FlutterFlowTheme.of(context).bodyMedium.override( + // fontFamily: 'Readex Pro', + // color: const Color(0xFF333333), + // fontSize: 13, + // letterSpacing: 0.0, + // ), + // ), + // ), + // Flexible( + // child: Align( + // alignment: const AlignmentDirectional(0, 0.05), + // child: Icon( + // Icons.arrow_forward_ios, + // color: FlutterFlowTheme.of(context).secondaryText, + // size: 10, + // ), + // ), + // ), + // ].divide(const SizedBox(width: 27)), + // ), + // ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () {}, + child: Container( + height: 30.rpx, + width: 30.rpx, + child: SvgPicture.asset( + 'assets/img/icon/expand.svg', + color: Colors.white, + ) + // Icon( + // Icons.arrow_forward_ios, + // color: Colors.white, + // // size: 14.rpx, + // ), + )), + ], + ), + // Container( + // width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.09, + // child: Container( + // width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.09, + // decoration: BoxDecoration(), + + // ), + // ), + ), + ), + ); + } +} diff --git a/lib/pages/mh_page/address_list_page.dart b/lib/pages/mh_page/address_list_page.dart index 4dbc295..6cbb597 100644 --- a/lib/pages/mh_page/address_list_page.dart +++ b/lib/pages/mh_page/address_list_page.dart @@ -1,10 +1,12 @@ import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appFontsize.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/NullDataComponentWidget.dart'; import 'package:vbvs_app/controller/mh_controller/address_list_controller.dart'; import 'package:vbvs_app/pages/mh_page/EmptyMessageWidget.dart'; import 'package:vbvs_app/pages/mh_page/address_module_widget.dart'; @@ -71,9 +73,7 @@ class AddressListPage extends GetView { Obx(() { if (controller.model.addressList!.isEmpty) { // 如果地址列表为空,显示 EmptyMessageWidget - return Expanded( - child: EmptyMessageWidget(), - ); + return Expanded(child: NullDataWidget()); } else { // 如果地址列表不为空,显示地址列表 return Expanded( @@ -160,24 +160,29 @@ class AddressListPage extends GetView { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Baseline( - baselineType: TextBaseline.alphabetic, - baseline: AppFontsize.normal_text_size * - 1.6, // 调整基线位置 - child: Text( - '+', - style: FlutterFlowTheme.of(context) - .titleSmall - .override( - fontFamily: 'Readex Pro', - color: Color(0xFF85F5FF), - fontSize: - AppFontsize.normal_text_size + - 12, // 让加号比文字稍大 - letterSpacing: 0, - ), - ), + // Baseline( + // baselineType: TextBaseline.alphabetic, + // baseline: AppFontsize.normal_text_size * + // 1.6, // 调整基线位置 + SvgPicture.asset( + 'assets/img/icon/plus.svg', + width: 42.rpx, + height: 42.rpx, ), + // Text( + // '+', + // style: FlutterFlowTheme.of(context) + // .titleSmall + // .override( + // fontFamily: 'Readex Pro', + // color: Color(0xFF85F5FF), + // fontSize: + // AppFontsize.normal_text_size + + // 12, // 让加号比文字稍大 + // letterSpacing: 0, + // ), + // ), + //), SizedBox(width: 10), // 加号和文字间距 Text( '添加新地址', diff --git a/lib/pages/mh_page/bluetooth.dart b/lib/pages/mh_page/bluetooth.dart index 042071b..1e12021 100644 --- a/lib/pages/mh_page/bluetooth.dart +++ b/lib/pages/mh_page/bluetooth.dart @@ -109,13 +109,13 @@ class _BluetoothState extends State { children: [ Image.asset( 'assets/images/active_bluetooth.png', - width: 42.rpx, - height: 42.rpx, + width: 68.rpx, + height: 68.rpx, ), SizedBox(height: 4), Text('已连接', style: TextStyle( - color: Colors.green, + color: Color(0xFF6BFDAC), fontSize: 26.rpx)), ], ), @@ -132,7 +132,7 @@ class _BluetoothState extends State { _buildMenuButton( context, '详情', "/devicePeopleInfo"), _buildMenuButton( - context, '人员资料', "/peopleInfoPage"), + context, '人员资料', "/peopleInfoPage"), _buildMenuButton( context, '房间选择', "/roomPickerPage"), _buildMenuButton( diff --git a/lib/pages/mh_page/book_info_page.dart b/lib/pages/mh_page/book_info_page.dart index c3cbe4d..e8052e2 100644 --- a/lib/pages/mh_page/book_info_page.dart +++ b/lib/pages/mh_page/book_info_page.dart @@ -14,7 +14,7 @@ class BookInfoPage extends GetView { Map data; BookInfoPage({required this.data}) { - // controller.getData(data["id"]); + controller.getData(data["id"]); } @override @@ -456,12 +456,11 @@ class BookInfoPage extends GetView { context) .bodyMedium .override( - fontFamily: - 'Readex Pro', - fontSize: AppFontsize - .normal_text_size, - letterSpacing: 0, - ), + fontFamily: + 'Readex Pro', + fontSize: 26.rpx, + letterSpacing: 0, + color: Colors.white), textAlign: TextAlign.end, ), ), @@ -622,12 +621,11 @@ class BookInfoPage extends GetView { context) .bodyMedium .override( - fontFamily: - 'Readex Pro', - fontSize: AppFontsize - .normal_text_size, - letterSpacing: 0, - ), + fontFamily: + 'Readex Pro', + fontSize: 26.rpx, + letterSpacing: 0, + color: Colors.white), textAlign: TextAlign.end, ), ), diff --git a/lib/pages/mh_page/device/device.dart b/lib/pages/mh_page/device/device.dart new file mode 100644 index 0000000..03c1355 --- /dev/null +++ b/lib/pages/mh_page/device/device.dart @@ -0,0 +1,439 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; + +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +import 'package:vbvs_app/controller/mh_controller/device_list_controller.dart'; + +class DeviceInfoWidget extends GetView { + int index; + DeviceListController deviceListController; + + DeviceInfoWidget({required this.index, required this.deviceListController}) {} + + @override + Widget build(BuildContext context) { + var device = deviceListController.model.deviceList[index]; + GlobalController globalController = Get.find(); + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), + child: Container( + // width: MediaQuery.sizeOf(context).width, + height: 381.rpx, + constraints: BoxConstraints( + minHeight: 140, + ), + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(16.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 33.rpx, 26.rpx, 0), + child: Container( + // width: MediaQuery.sizeOf(context).width, + height: 381.rpx, + constraints: BoxConstraints( + minHeight: 106, + ), + + child: Container( + // width: MediaQuery.sizeOf(context).width, + height: 381.rpx, + constraints: BoxConstraints( + minHeight: 130, + ), + + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + deviceListController.model.deviceList[index]['name'] ?? + 'SWES系列 01号智能一键入眠床', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + ), + maxLines: 1, // 限制显示一行 + overflow: TextOverflow.ellipsis, // 超出部分显示省略号 + ), + Container( + margin: EdgeInsets.only(top: 36.rpx), + width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.065, + constraints: BoxConstraints( + minHeight: 55, + ), + + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: InkWell( + onTap: () async { + // GlobalController globalController = Get.find(); + // var tmp = globalController.model.deviceMain; + // BedController bedController = Get.find(); + // bedController.websocketSend(2); + // globalController.model.deviceMain = device; + // globalController.updateAll(); + // bedController.websocketSend(1); + // var result = await Get.toNamed("/bodyChart"); + // bedController.websocketSend(2); + // globalController.model.deviceMain = tmp; + }, + child: Container( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: '设备ID:' + + (deviceListController.model + .deviceList[ + index]['id'] ?? + ''), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: + Color(0xFFC8CBD2), + fontSize: 26.rpx, + letterSpacing: 0, + lineHeight: 1), + ), + TextSpan( + text: + ' (${deviceListController.model.deviceList[index]['status'] ?? ''})', + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + 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] + ['roomName'] ?? + ''), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFFC8CBD2), + fontSize: 26.rpx, + letterSpacing: 0, + lineHeight: 1), + ), + ), + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + '设备状态:' + + (deviceListController + .model + .deviceList[index]["status"] + ?["status"] + ?.toString() ?? + ''), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFFC8CBD2), + fontSize: 26.rpx, + letterSpacing: 0, + lineHeight: 1), + ), + ) + ].divide(SizedBox(height: 36.rpx)), + ), + ), + ), + ), + Align( + alignment: AlignmentDirectional(0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width * 0.21, + height: 90.rpx, + child: FFButtonWidget( + onPressed: () { + // deviceControllerChange(device); + }, + text: '控制', + options: FFButtonOptions( + color: Color(0XFF85F5FF), + textStyle: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 28.rpx, + letterSpacing: 0, + ), + elevation: 0, + borderSide: BorderSide( + color: Colors.transparent, + width: 1, + ), + borderRadius: BorderRadius.circular(16.rpx), + ), + ), + ), + ), + ], + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 36.rpx, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: 130, + constraints: BoxConstraints( + minHeight: 1, + maxHeight: 1, + ), + decoration: BoxDecoration( + color: Color(0xFFB6BBC9), + ), + ), + ), + Flexible( + child: Container( + margin: EdgeInsets.only(right: 26.rpx), + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + constraints: BoxConstraints( + minHeight: 60, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + InkWell( + onTap: () async { + if (device['type'] == 1) { + globalController.model.deviceMain = device; + await Get.toNamed("/deviceShare"); + globalController.getDeviceList(); + } + }, + child: Container( + height: MediaQuery.sizeOf(context).height * 0.1, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Align( + alignment: AlignmentDirectional(1, 0), + child: Container( + width: 42.rpx, + height: 42.rpx, + child: SvgPicture.asset( + 'assets/images/group.svg', + color: Color(0xFF85F5FF), + ), + )), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (device['type'] == 1) + Text( + '已分享:', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color(0xFF333333), + ), + ), + if (device['type'] == 1) + Padding( + padding: + EdgeInsetsDirectional.fromSTEB( + 5, 0, 5, 0), + child: Text( + // '0', + deviceListController + .model.deviceList[index] + ['shareNum'] ?? + '0', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFFE55E92), + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + if (device['type'] == 1) + Text( + '人', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color(0xFF333333), + ), + ), + if (device['type'] == 2) + Text( + '来自', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color(0xFF333333), + ), + ), + if (device['type'] == 2) + Padding( + padding: + EdgeInsetsDirectional.fromSTEB( + 5, 0, 5, 0), + child: Text( + '${device['suname']?.length > 5 ? device['suname'].substring(0, 5) + '...' : device['suname']}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFFE55E92), + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + if (device['type'] == 2) + Text( + '的分享', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: 21.rpx, + letterSpacing: 0, + color: Color(0xFF333333), + ), + ), + ], + ), + ].divide(SizedBox(width: 6)), + ), + ), + ), + InkWell( + onTap: () { + var a = [device["bindMacA"]]; + if ("${device["bindMacB"]}".length > 6) { + a.add(device["bindMacB"]); + } + Get.toNamed("/sleepWebview", arguments: a); + }, + child: Container( + height: MediaQuery.sizeOf(context).height * 0.1, + constraints: BoxConstraints( + minHeight: 25, + ), + alignment: Alignment.center, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Align( + alignment: AlignmentDirectional(0, 0), + child: SvgPicture.asset( + "assets/images/table.svg", + width: 24.rpx, + height: 24.rpx, + color: Color(0xFF85F5FF), + ), + ), + SizedBox(width: 5), + Text( + '睡眠报告', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 21.rpx, + letterSpacing: 0, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/mh_page/device_list.dart b/lib/pages/mh_page/device_list.dart new file mode 100644 index 0000000..402266a --- /dev/null +++ b/lib/pages/mh_page/device_list.dart @@ -0,0 +1,134 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/NullDataComponentWidget.dart'; +import 'package:vbvs_app/pages/mh_page/device/device.dart'; +import 'package:vbvs_app/pages/mh_page/searchWidget.dart'; + +import '../../controller/mh_controller/device_list_controller.dart'; + +class DeviceListPage extends StatefulWidget { + const DeviceListPage({super.key}); + + @override + State createState() => _DeviceListPageState(); +} + +class _DeviceListPageState extends State { + final scaffoldKey = GlobalKey(); + DeviceListController controller = Get.find(); + BoxConstraints? bodysize; + + @override + void initState() { + super.initState(); + controller.model.keyword = ''; + controller.getDeviceList(); + } + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return 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: 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: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + backgroundColor: Colors.transparent, + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 10, 0, 23), + child: SearchWidget( + keyword: controller.model.keyword, + color: controller.model.color, + hint: "检索设备", + onChange: (d) { + controller.model.keyword = d; + }, + findCallback: () { + controller.getDeviceList(); + }, + ), + ), + Obx(() { + if (controller.model.deviceList == null || + controller.model.deviceList.isEmpty) { + return Expanded(child: NullDataWidget()); + } + + // 如果 deviceList 不为空,渲染列表 + return Expanded( + child: ListView( + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: controller.model.deviceList + .asMap() + .entries + .map((e) => DeviceInfoWidget( + index: e.key, + deviceListController: controller, + )) + .toList() + .divide(const SizedBox(height: 10)) + .addToEnd(const SizedBox(height: 100)), + ), + ); + }), + ], + ), + ), + ), + )); + }); + } +} diff --git a/lib/pages/mh_page/device_share_page.dart b/lib/pages/mh_page/device_share_page.dart new file mode 100644 index 0000000..f9210af --- /dev/null +++ b/lib/pages/mh_page/device_share_page.dart @@ -0,0 +1,672 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/CommonVariables.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/main_bottom/global_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/pages/mh_page/ShareUserWidget.dart'; + +class ShareDeviceWidget extends GetView { + final scaffoldKey = GlobalKey(); + + 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(); + final _phoneController = TextEditingController(); + + @override + Widget build(BuildContext context) { + var deviceController = Get.find(); + controller.model.msg = ""; + controller.model.show = 0; + controller.model.type = 1; + return 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: const IconThemeData(color: Colors.white), + titleSpacing: 0, + 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: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + actions: [], + centerTitle: false, + ), + key: scaffoldKey, + backgroundColor: Colors.transparent, + body: SingleChildScrollView( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + child: Padding( + padding: + EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0, 30.rpx, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + color: const Color(0xFF003058), + borderRadius: BorderRadius.circular(16.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 49.rpx, 30.rpx, 80.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Text( + '将以下设备分享给您的家人或朋友 ', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0.0, + lineHeight: 1, + ), + ), + Text( + '设备ID:${deviceController.model.deviceMain['mac']}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF6BFDAC), + fontSize: 26.rpx, + letterSpacing: 0.0, + lineHeight: 1), + ), + ].divide(SizedBox(height: 65.rpx)), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 80.rpx, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + constraints: const BoxConstraints( + minHeight: 46, + ), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Align( + alignment: + const AlignmentDirectional(0, 0), + child: Form( + key: _formKey, + child: TextFormField( + controller: _phoneController, + decoration: InputDecoration( + hintText: '请输入对方手机号', + hintStyle: + FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 36.rpx, + ), + enabledBorder: + const UnderlineInputBorder( + borderSide: BorderSide( + color: Color(0xFF929699), + width: 0), + ), + focusedBorder: + const UnderlineInputBorder( + borderSide: BorderSide( + color: Color(0xFF929699), + width: 0), + ), + errorBorder: + const UnderlineInputBorder( + borderSide: BorderSide( + color: Colors.red, + width: 0), + ), + focusedErrorBorder: + const UnderlineInputBorder( + borderSide: BorderSide( + color: Colors.redAccent, + width: 0), + ), + contentPadding: + const EdgeInsets.only( + left: 10, bottom: 5), + ), + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + 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) { + controller.model.phone = 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( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(top: 30.rpx), + onTap: () {}, + child: Container( + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: Color(0xFF85F5FF), + width: 0), // 下边线 + ), + ), + child: Text( + '点击复制APP下载链接', + style: TextStyle( + color: Color(0xFF85F5FF), // 蓝色文字 + + fontSize: 22.rpx, + ), + ), + )), + // Container( + // width: MediaQuery.sizeOf(context).width, + // constraints: const BoxConstraints( + // minHeight: 46, + // ), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(0), + // ), + // child: Align( + // alignment: + // const AlignmentDirectional(0, 0), + // child: Obx(() { + // if (controller.model.show == 0) { + // return Container(); + // } else { + // return GestureDetector( + // onTap: controller + // .model.msg!.isNotEmpty + // ? () { + // Clipboard.setData( + // ClipboardData( + // text: CommonVariables + // .shareText)); + // showToast( + // "复制成功,粘贴分享APP下载链接!", + // color: color_success); + // } + // : null, // 不可点击时设置为 null + // child: RichText( + // textAlign: TextAlign + // .center, // 设置整个 RichText 内容居中 + // text: TextSpan( + // children: + // controller.model.msg! + // .isNotEmpty + // ? [ + // TextSpan( + // text: controller + // .model + // .msg! + + // "!", // 第一部分文本 + // style: FlutterFlowTheme.of( + // context) + // .bodyMedium + // .override( + // fontFamily: + // 'Readex Pro', + // color: const Color( + // 0xFFE55E92), // 设置为粉红色 + // fontSize: + // 26.rpx, + // letterSpacing: + // 0.0, + // ), + // ), + // const TextSpan( + // text: + // '\n', // 添加换行 + // ), + // WidgetSpan( + // child: SizedBox( + // height: 20 + // .rpx), // 添加间距 + // ), + // TextSpan( + // text: + // '点击复制APP下载链接', // 第二部分文本 + // style: FlutterFlowTheme.of( + // context) + // .bodyMedium + // .override( + // 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, + // ), + // ), + // ], + // ), + // ), + // ); + // } + // })), + // ), + + Obx( + () => GestureDetector( + onTap: () { + // 当点击时,将 type 设置为 0(允许控制) + controller.model.type = 1; + controller.updateAll(); + }, + child: Container( + margin: EdgeInsets.only(top: 76.rpx), + 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: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + ), + Radio( + 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: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + ), + Radio( + 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( + alignment: const AlignmentDirectional(0, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 46.rpx, 0, 0), + child: Container( + width: 108, + height: 31, + decoration: BoxDecoration(), + child: FFButtonWidget( + onPressed: () async { + //todo 1:验证用户是否存在 2:发送邀请 + // controller.model.show = 1; + // String msg = + // await controller.sendInvite( + // controller.model.phone, + // deviceController + // .model.deviceMain['mac']); + // if (msg != null && msg.isNotEmpty) { + // controller.model.msg = msg; + // } + // controller.updateAll(); + }, + text: '发送邀请', + options: FFButtonOptions( + height: 60.rpx, + padding: + EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0, 30.rpx, 0), + color: const Color(0xFF84F5FF), + textStyle: + FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF011D33), + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + elevation: 0, + borderRadius: + BorderRadius.circular(50), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Expanded( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 100.rpx, 0, 32.rpx), + child: Container( + width: MediaQuery.sizeOf(context).width, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional(-1, 0), + child: Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(14, 0, 0, 16), + child: Text( + '已分享用户', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0.0, + lineHeight: 1), + ), + ), + ), + Obx( + () { + // 检查 shareUser 是否为空或数量为 0 + if (controller.model.shareUser == + null || + controller + .model.shareUser!.isEmpty) { + // return Container( + // alignment: AlignmentDirectional + // .centerStart, // 确保文字靠左对齐 + // padding: EdgeInsets.symmetric( + // horizontal: 16.0), // 根据需要设置内边距 + // child: Text( + // "暂无分享!", + // textAlign: TextAlign.left, // 文字左对齐 + // style: FlutterFlowTheme.of(context) + // .bodyMedium, // 可根据需要自定义样式 + // ), + // ); + return EmptyMessageWidget( + imagePath: + "assets/images/emptyUser.png", + ); + } + + // 否则显示正常的 ListView + return ListView( + controller: + scrollController, // 绑定 ScrollController + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: (controller.model.shareUser! + .asMap() + .entries + .map((e) => ShareUserWidget( + index: e.key, + repairListController: + controller)) + .toList() as List) + // .divide(const SizedBox( + // height: 13, + // )) + .addToEnd(const SizedBox( + height: + AppConstants.list_end_height, + )), + ); + }, + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + )), + )); + } +} diff --git a/lib/pages/mh_page/experience_store_widget.dart b/lib/pages/mh_page/experience_store_widget.dart index 5f6b1a3..44538ce 100644 --- a/lib/pages/mh_page/experience_store_widget.dart +++ b/lib/pages/mh_page/experience_store_widget.dart @@ -59,7 +59,6 @@ class ExperienceStoreWidget extends GetView { fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, - fontWeight: FontWeight.bold, letterSpacing: 0, ), ), diff --git a/lib/pages/mh_page/new_mine_page.dart b/lib/pages/mh_page/new_mine_page.dart index 157a3d5..ca0609d 100644 --- a/lib/pages/mh_page/new_mine_page.dart +++ b/lib/pages/mh_page/new_mine_page.dart @@ -279,28 +279,30 @@ class _MinePageState extends State { // 直接使用 SingleChildScrollView child: Column( children: [ - _buildListTile( - Icons.receipt_long, '我的订单', '快捷查看我在网上的订单记录', + _buildListTile('assets/img/icon/order.svg', + '我的订单', '快捷查看我在网上的订单记录', showTopLine: true, path: "/issueListpage"), - _buildListTile(Icons.store_mall_directory, '门店体验', - '如果想免费体验智能设备,可在此进行提前预约', + _buildListTile('assets/img/icon/store.svg', + '门店体验', '如果想免费体验智能设备,可在此进行提前预约', path: "/experienceStorePage"), _buildListTile( - Icons.build, + 'assets/img/icon/repair.svg', '设备报修', '当您的智能设备需要报修时,可以通过该功能联系解决,', path: '/deviceRepairPage', ), - _buildListTile( - Icons.shopping_cart, '网上商城', '最新的智能产品线上购买服务', + _buildListTile('assets/img/icon/mall.svg', '网上商城', + '最新的智能产品线上购买服务', path: "/issueListpage"), - _buildListTile( - Icons.location_on, '地址管理', '用于收货和报修时联系您', + _buildListTile('assets/img/icon/address.svg', + '地址管理', '用于收货和报修时联系您', path: "/addressListPage"), - _buildListTile(Icons.help_outline, '问题与帮助', - '常见的问题汇总,如:智能床连接流程、如何查看睡眠报告', + _buildListTile('assets/img/icon/help.svg', + '问题与帮助', '常见的问题汇总,如:智能床连接流程、如何查看睡眠报告', path: "/issueListpage"), - _buildListTile(Icons.headset_mic, '在线客服', + _buildListTile( + 'assets/img/icon/customer_service.svg', + '在线客服', '购买和使用智能床过程中,如果遇到疑问可与客服进行联系', path: "/issueListpage"), ], @@ -331,7 +333,7 @@ class _MinePageState extends State { /// 构建列表项(带分隔线) Widget _buildListTile( - IconData icon, + String svgPath, String title, String subtitle, { // VoidCallback? onTap, @@ -359,7 +361,13 @@ class _MinePageState extends State { padding: EdgeInsets.fromLTRB(40.rpx, 0.rpx, 40.rpx, 0.rpx), child: Row( children: [ - Icon(icon, color: const Color(0xFF85F5FF), size: 28.rpx), + Container( + child: SvgPicture.asset( + svgPath, + width: 42.rpx, + height: 42.rpx, + ), + ), SizedBox(width: 30.rpx), Expanded( child: Column( diff --git a/lib/pages/mh_page/people_info.dart b/lib/pages/mh_page/people_info.dart index d83908a..eeb5ac4 100644 --- a/lib/pages/mh_page/people_info.dart +++ b/lib/pages/mh_page/people_info.dart @@ -35,10 +35,7 @@ class _PeopleInfoState extends State { // } getLine() { - return Container( - height: 1, - color: stringToColor("#152676"), - ); + return Container(height: 0.5.rpx, color: Color(0xFFD8D8D8)); } @override @@ -163,7 +160,7 @@ class _PeopleInfoState extends State { .bodyMedium .override( fontFamily: 'Readex Pro', - color: stringToColor("#9EA4B7"), + color: Color(0XFF011D33), letterSpacing: 0, fontSize: 30.rpx, ), @@ -754,6 +751,7 @@ class _PeopleInfoState extends State { ], ), ), + getLine(), ], ), ) diff --git a/lib/pages/mh_page/repair_history_widget.dart b/lib/pages/mh_page/repair_history_widget.dart index cdc4181..57c2da2 100644 --- a/lib/pages/mh_page/repair_history_widget.dart +++ b/lib/pages/mh_page/repair_history_widget.dart @@ -1,5 +1,6 @@ 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/appColors.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; @@ -200,8 +201,24 @@ class RepairHistoryWidget extends GetView { '', style: TextStyle(color: Colors.white, fontSize: 26.rpx), ), - Icon(Icons.arrow_forward_ios, - color: Colors.white, size: 30.rpx), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () {}, + child: Container( + height: 30.rpx, + width: 30.rpx, + child: SvgPicture.asset( + 'assets/img/icon/expand.svg', + color: Colors.white, + ) + // Icon( + // Icons.arrow_forward_ios, + // color: Colors.white, + // // size: 14.rpx, + // ), + )), ], ) ], diff --git a/lib/pages/mh_page/searchWidget.dart b/lib/pages/mh_page/searchWidget.dart index 5552123..aebd218 100644 --- a/lib/pages/mh_page/searchWidget.dart +++ b/lib/pages/mh_page/searchWidget.dart @@ -22,12 +22,12 @@ class SearchWidget extends GetView { @override Widget build(BuildContext context) { return Padding( - padding: EdgeInsetsDirectional.fromSTEB(25, 0, 25, 0), + padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), child: Container( width: double.infinity, decoration: BoxDecoration( color: themeController.currentColor.sc3, - borderRadius: BorderRadius.circular(20.rpx), + borderRadius: BorderRadius.circular(16.rpx), ), child: Padding( padding: EdgeInsetsDirectional.fromSTEB(35.rpx, 0, 35.rpx, 0), @@ -39,24 +39,21 @@ class SearchWidget extends GetView { child: Row( mainAxisSize: MainAxisSize.max, children: [ - Padding( - padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0), - child: Container( - width: 25.rpx, - height: 25.rpx, - // width: double.infinity, - decoration: BoxDecoration(), - child: SvgPicture.asset( - 'assets/img/icon/query.svg', - fit: BoxFit.cover, - color: stringToColor("#333333"), //固定 - ), + Container( + width: 25.rpx, + height: 25.rpx, + // width: double.infinity, + decoration: BoxDecoration(), + child: SvgPicture.asset( + 'assets/img/icon/query.svg', + fit: BoxFit.cover, + color: stringToColor("#333333"), //固定 ), ), Expanded( child: Container( width: 100.rpx, - height: 80.rpx, + height: 60.rpx, decoration: BoxDecoration( color: FlutterFlowTheme.of(context).secondaryBackground, @@ -79,10 +76,10 @@ class SearchWidget extends GetView { hintStyle: FlutterFlowTheme.of(context) .labelMedium .override( - fontFamily: 'Inter', - fontSize: 26.rpx, - letterSpacing: 0.0, - ), + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + color: Color(0XFFC8CBD2)), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0x00000000), @@ -113,12 +110,15 @@ class SearchWidget extends GetView { ), filled: false, fillColor: themeController.currentColor.sc22, + contentPadding: EdgeInsets.symmetric( + vertical: 12.rpx, horizontal: 12.rpx), // 关键设置 ), style: FlutterFlowTheme.of(context) .bodyMedium .override( fontFamily: 'Inter', fontSize: 26.rpx, + color: Colors.black, letterSpacing: 0.0, ), cursorColor: @@ -161,7 +161,6 @@ class SearchWidget extends GetView { ), ), ), - ); } } diff --git a/lib/routers/mh_routers.dart b/lib/routers/mh_routers.dart index 95cc7a2..0001d25 100644 --- a/lib/routers/mh_routers.dart +++ b/lib/routers/mh_routers.dart @@ -1,6 +1,7 @@ import 'package:ef/ef.dart'; import 'package:flutter/cupertino.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; + import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/main.dart'; @@ -11,7 +12,9 @@ import 'package:vbvs_app/pages/mh_page/address_list_page.dart'; import 'package:vbvs_app/pages/mh_page/apply_repair_page.dart'; import 'package:vbvs_app/pages/mh_page/book_info_page.dart'; import 'package:vbvs_app/pages/mh_page/book_success_page.dart'; +import 'package:vbvs_app/pages/mh_page/device_list.dart'; 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/edit_bed.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'; @@ -64,6 +67,8 @@ var mhroutes = { "/findPasswordPage": (context) => FindPasswordPage(), "/loginPage": (context) => MHTLoginPage(), "/updatePasswordPage": (context) => UpdatePasswordPage(), + "/deviceSharePage": (context) => ShareDeviceWidget(), + "/deviceListPage": (context) => DeviceListPage(), }; var mhonGenerateRoute = (RouteSettings settings) { final String? name = settings.name; // 获取路由名称,如 /news 或 /search @@ -74,39 +79,16 @@ var mhonGenerateRoute = (RouteSettings settings) { int loginStatus = userInfoController.model.login!; // 检查用户是否已登录,如果未登录且路由不是登录相关页面,跳转到登录页面 - // if (loginStatus != 1) { - // // 如果用户未登录且访问的不是登录页面等,展示提示并重定向 - // if (settings.name != "/loginPage" && - // settings.name != "/otherLoginPage" && - // settings.name != "/mianPageBottomChange") { - // TopSlideNotification.show( - // Get.context!, - // text: "必须登录提示".tr, - // textColor: themeController.currentColor.sc9, - // ); - // // 创建新的 RouteSettings,并修改 name 为 /loginPage - // final updatedSettings = RouteSettings( - // name: "/loginPage", - // arguments: settings.arguments, - // ); - - // // 创建一个新的路由,跳转到登录页面 - // return CupertinoPageRoute( - // settings: updatedSettings, - // builder: (context) => pageContentBuilder!(context), - // ); - // } - // } if (loginStatus != 1) { if (settings.name != "/loginPage" && settings.name != "/otherLoginPage" && settings.name != "/mianPageBottomChange") { - TopSlideNotification.show( - navigatorKey.currentContext!, - text: "必须登录提示".tr, - textColor: themeController.currentColor.sc9, - ); + // TopSlideNotification.show( + // navigatorKey.currentContext!, + // text: "必须登录提示".tr, + // textColor: themeController.currentColor.sc9, + // ); return CupertinoPageRoute( settings: RouteSettings( name: "/loginPage",