初始化项目
This commit is contained in:
27
lib/common/color/appColors.dart
Normal file
27
lib/common/color/appColors.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
|
||||
class AppColors {
|
||||
// 定义颜色常量
|
||||
static const Color text_selected_color = Color(0xFFD3B684); //选中文本
|
||||
static const Color text_default_color = Color(0xFFFFFFFF); //默认文本
|
||||
|
||||
static const Color button_active_color = Color(0xFFD3B684); //可点击按钮
|
||||
static const Color button_inactive_color = Color(0xFFD3D3D3); //不可点击按钮
|
||||
static const Color bg_color = Color(0xFF000750); //背景色
|
||||
static const Color input_bg_color = Color(0xFFF3F5F6); //输入框背景色
|
||||
static const Color input_hint_text_color = Color(0xFFF3F5F6); //hinttext
|
||||
static const Color input_split_color = Color(0xFFF3F5F6); //分隔符
|
||||
static const Color textColor = Color(0xFF333333); //普通文本
|
||||
|
||||
static const Color buttonColor = Color(0xFF03A9F4);
|
||||
static const Color borderColor = Color(0xFFE0E0E0);
|
||||
static const Color errorColor = Color(0xFFB00020);
|
||||
|
||||
Color check_Color = stringToColor('#409EFF');
|
||||
Color repair_Color = stringToColor('#409EFF');
|
||||
Color finish_Color = stringToColor('#71E2A3');
|
||||
Color unOp_Color = stringToColor('#FF4949');
|
||||
|
||||
Color press_color = stringToColor("#eaeaea");
|
||||
}
|
||||
24
lib/common/color/appConstants.dart
Normal file
24
lib/common/color/appConstants.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
|
||||
class AppConstants {
|
||||
// App-related constants
|
||||
static const int code_time = 60; //验证码倒计时
|
||||
static const int limit = 10; //分页数量
|
||||
|
||||
static const double list_end_height = 26; //列表结尾空白高度
|
||||
static const double list_ano_end_height = 100; //列表结尾空白高度
|
||||
static const double list_start_height = 13; //列表开头空白高度
|
||||
|
||||
static const double page_button_bottom_padding = 45; //页面底部按钮距离底部距离
|
||||
|
||||
double main_left_right_padding = 30.rpx; //页面左右布局间距
|
||||
double content_left_right_padding = 15.rpx; //页面左右内容间距
|
||||
|
||||
double normal_container_radius = 24.rpx; //普通容器圆角
|
||||
double button_container_radius = 100.rpx; //按钮容器圆角
|
||||
|
||||
double text_padding_up_dowm_p = 5.rpx; //段落文字上下间距
|
||||
|
||||
double normal_text_fontSize = 26.rpx; //普通文字字号
|
||||
double title_text_fontSize = 30.rpx; //标题文字字号
|
||||
}
|
||||
10
lib/common/color/appFontsize.dart
Normal file
10
lib/common/color/appFontsize.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
|
||||
class AppFontsize {
|
||||
// 定义文字常量
|
||||
static double title_size = 15.px; //标题
|
||||
static double normal_text_size = 13.px; //普通文本
|
||||
static double small_text_size = 11.px; //小号文本
|
||||
static double smaller_text_size = 9.px; //小号文本
|
||||
static double explain_size = 8.px; //说明文本
|
||||
}
|
||||
32
lib/common/color/app_uri.dart
Normal file
32
lib/common/color/app_uri.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
// lib/api_endpoints.dart
|
||||
|
||||
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
||||
|
||||
class ApiEndpoints {
|
||||
// Base URL of the API
|
||||
static String baseUrl = '${CommonVariables.apiUrl}/api';
|
||||
|
||||
// Endpoints
|
||||
static String signIn = '$baseUrl/auth/account/info/signIn'; //登录
|
||||
static String getUserInfo = '$baseUrl/user/info'; //获取用户信息
|
||||
static String updateProfile = '$baseUrl/user/updateProfile'; //更新用户信息
|
||||
static String login_code = '$baseUrl/auth/msg/signIn'; //登录验证码
|
||||
static String wx_auth_code = '$baseUrl/auth/msg/wxAuth'; //微信授权验证码
|
||||
static String register = '$baseUrl/auth/account/info/signUp'; //注册
|
||||
static String reset_code = '$baseUrl/auth/msg/restore'; //重置验证码
|
||||
static String reset_pd = '$baseUrl/auth/account/info/restore/pw'; //重置密码
|
||||
static String updateUserInfo =
|
||||
'$baseUrl/auth/account/info/nameAndHead'; //更新用户资料
|
||||
static String autoLogin = '$baseUrl/auth/account/info/autoLogin'; //自动登录
|
||||
|
||||
//订单管理
|
||||
static String orderList = "/api/order/info/list"; //订单列表
|
||||
static String orderQianshou = "/api/order/info/get"; //签收
|
||||
|
||||
//分享设备
|
||||
static String deviceInvite = '$baseUrl/api/device/info/share'; //分享设备
|
||||
|
||||
// Add more endpoints as needed
|
||||
//添加/床垫控制日志
|
||||
static String addLog = '$baseUrl/oplog/add';
|
||||
}
|
||||
19
lib/common/color/app_uri_status.dart
Normal file
19
lib/common/color/app_uri_status.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
// lib/http_status_codes.dart
|
||||
|
||||
class HttpStatusCodes {
|
||||
// Success codes
|
||||
static const int ok = 1;
|
||||
static const int created = 201;
|
||||
static const int accepted = 202;
|
||||
|
||||
// Client error codes
|
||||
static const int badRequest = 400;
|
||||
static const int unauthorized = 401;
|
||||
static const int forbidden = 403;
|
||||
static const int notFound = 404;
|
||||
|
||||
// Server error codes
|
||||
static const int internalServerError = 500;
|
||||
static const int notImplemented = 501;
|
||||
static const int serviceUnavailable = 503;
|
||||
}
|
||||
9
lib/common/color/delivery_status.dart
Normal file
9
lib/common/color/delivery_status.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
class DeliveryStatus {
|
||||
// 私有构造函数,防止实例化
|
||||
const DeliveryStatus._();
|
||||
|
||||
// 物流状态常量
|
||||
static const String no_de = '待发货';//下单之后待发货
|
||||
static const String has_de = '已发货';//确认发货
|
||||
static const String completed = '已签收';//签收
|
||||
}
|
||||
37
lib/common/color/order_status.dart
Normal file
37
lib/common/color/order_status.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
class OrderStatus {
|
||||
// 私有构造函数,防止实例化
|
||||
const OrderStatus._();
|
||||
|
||||
// 订单状态常量值
|
||||
static const int noPay = 1; // 已下单,待支付(both)
|
||||
static const int paid = 2; // 已支付(app),待确认(web)
|
||||
static const int toBeShipped = 3; // 已确认(web),待发货(app)
|
||||
static const int toBeReceived = 4; // 已发货(web),待签收(app)
|
||||
static const int received = 5; // 已签收(app),待完成(web)
|
||||
static const int closed = 6; // 已关闭(both)
|
||||
static const int completed = 7; // 已完成(web),已签收(app)
|
||||
|
||||
// 订单状态编号与描述的映射
|
||||
static const Map<int, String> statuses = {
|
||||
1: '待支付', // 已下单,待支付(both)
|
||||
2: '已支付', // 已支付(app),待确认(web)
|
||||
3: '待发货', // 已确认(web),待发货(app)
|
||||
4: '待签收', // 已发货(web),待签收(app)
|
||||
5: '已签收', // 已签收(app),待完成(web)
|
||||
6: '已关闭', // 已关闭(both)
|
||||
7: '已签收', // 已完成(web),已签收(app)
|
||||
};
|
||||
|
||||
// 根据编号获取状态名称的描述
|
||||
static String getDescriptionByCode(int code) {
|
||||
return statuses[code] ?? '未知状态';
|
||||
}
|
||||
|
||||
// 根据状态名称获取编号
|
||||
static int getCodeByDescription(String description) {
|
||||
return statuses.entries
|
||||
.firstWhere((element) => element.value == description,
|
||||
orElse: () => MapEntry(0, '未知状态'))
|
||||
.key;
|
||||
}
|
||||
}
|
||||
10
lib/common/color/pay_status.dart
Normal file
10
lib/common/color/pay_status.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
class PayStatus {
|
||||
// 私有构造函数,防止实例化
|
||||
const PayStatus._();
|
||||
|
||||
// 支付状态常量
|
||||
static const String no_pay = '待支付';
|
||||
static const String have_pay = '已支付';
|
||||
static const String close = '已关闭';
|
||||
|
||||
}
|
||||
9
lib/common/color/repair_status.dart
Normal file
9
lib/common/color/repair_status.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
class RepairStatus {
|
||||
// 私有构造函数,防止实例化
|
||||
const RepairStatus._();
|
||||
|
||||
// 维修状态常量
|
||||
static const String pending = '审核中';
|
||||
static const String approved = '审核通过';
|
||||
static const String completed = '已完成';
|
||||
}
|
||||
35
lib/common/util/CommonVariables.dart
Normal file
35
lib/common/util/CommonVariables.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
class CommonVariables {
|
||||
static bool isNetWorkOn = false;
|
||||
static bool test = false;
|
||||
static String supabaseUrl = "https://mht1.he-info.cn";
|
||||
// static String wsUrl = "ws://mht-server.he-info.cn/ws";
|
||||
// static String apiUrl = "https://mht-server.he-info.cn";
|
||||
// static String shoph5Url = "https://mht-web.he-info.cn";
|
||||
// static String supabaseUrl = "https://zhmht.swes.com.cn:3443";
|
||||
// static String wsUrl = "wss://zhmht.swes.com.cn:8089/ws";
|
||||
// static String apiUrl = "https://zhmht.swes.com.cn:8089";
|
||||
static String wsUrl = "ws://192.168.1.129:8088/ws";
|
||||
static String apiUrl = "http://192.168.1.129:8088";
|
||||
static String shoph5Url = "https://zhmht.swes.com.cn:1443";
|
||||
static String sleepUrl = "https://alltoone.he-info.cn";
|
||||
static String efKey = "ef_key";
|
||||
|
||||
// // android app 内部更新地址
|
||||
// static String androidInternalUpgradeUrl = "http://192.168.0.112:1234";
|
||||
|
||||
// 企业微信客服拉起的url地址
|
||||
static String wxKfUrl = "https://work.weixin.qq.com/kfid/kfc7d2337b9c07b1269";
|
||||
// 企业微信ID
|
||||
static String wxCorpId = "ww51feda6026280cd0";
|
||||
//ICP备案号
|
||||
static String ICPRightCode = "皖ICP备2024068219号-1A";
|
||||
//公司名称
|
||||
static String enterpriseName = "合肥眠花糖家具有限责任公司";
|
||||
//备案时间
|
||||
static String ICPTime = "2022-2025";
|
||||
|
||||
// 分享复制文字信息
|
||||
static String shareText = "您的朋友邀请您使用《智慧眠花糖》APP,请复制后面链接在浏览器中打开! " +
|
||||
shoph5Url +
|
||||
"/#/pages/download/download";
|
||||
}
|
||||
43
lib/common/util/FitTool.dart
Normal file
43
lib/common/util/FitTool.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
class FitTool {
|
||||
static double rpx = 0;
|
||||
static bool isInit = false;
|
||||
static init(double v) {
|
||||
if (v < 1) {
|
||||
return;
|
||||
}
|
||||
if (isInit == false) {
|
||||
isInit = true;
|
||||
rpx = v / 750.0;
|
||||
}
|
||||
}
|
||||
|
||||
static double getPx(double size) {
|
||||
return rpx * size * 2.0;
|
||||
}
|
||||
|
||||
static double getRpx(double size) {
|
||||
return rpx * size;
|
||||
}
|
||||
}
|
||||
|
||||
extension FitInt on int {
|
||||
double get px {
|
||||
return FitTool.getPx(this.toDouble());
|
||||
}
|
||||
|
||||
double get rpx {
|
||||
return FitTool.getRpx(this.toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
extension FitDouble on double {
|
||||
double get px {
|
||||
return FitTool.getPx(this);
|
||||
}
|
||||
|
||||
double get rpx {
|
||||
return FitTool.getRpx(this);
|
||||
}
|
||||
}
|
||||
327
lib/common/util/MyUtils.dart
Normal file
327
lib/common/util/MyUtils.dart
Normal file
@@ -0,0 +1,327 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
Future<void> initDataEf({String key = ""}) async {
|
||||
await ef.init(
|
||||
'${CommonVariables.supabaseUrl}/',
|
||||
key,
|
||||
nosqlEnableWebsocket: false,
|
||||
);
|
||||
}
|
||||
|
||||
class MyUtils {
|
||||
static String timestampToDateString(int timestamp) {
|
||||
DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||
|
||||
String formattedDate =
|
||||
'${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')} '
|
||||
'${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
static String hidePhoneNumber(String phoneNumber) {
|
||||
if (phoneNumber.length != 11) {
|
||||
// 检查手机号是否为11位
|
||||
throw Exception("手机号格式不正确");
|
||||
}
|
||||
|
||||
// 将中间四位替换为星号
|
||||
return phoneNumber.replaceRange(3, 7, '****');
|
||||
}
|
||||
|
||||
static double initialScrollOffset = 0.0;
|
||||
// 判断手机号格式是否正确的方法
|
||||
static bool isValidPhoneNumber(String phoneNumber) {
|
||||
final RegExp phoneRegExp = RegExp(r'^1[3-9]\d{9}$');
|
||||
return phoneRegExp.hasMatch(phoneNumber);
|
||||
}
|
||||
|
||||
static Future<void> makePhoneCall(String phoneNumber) async {
|
||||
final Uri launchUri = Uri(
|
||||
scheme: 'tel',
|
||||
path: phoneNumber,
|
||||
);
|
||||
|
||||
if (await canLaunchUrl(launchUri)) {
|
||||
await launchUrl(launchUri);
|
||||
} else {
|
||||
throw '无法拨打电话';
|
||||
}
|
||||
}
|
||||
|
||||
static String formatDateTime(DateTime dateTime) {
|
||||
// 定义日期格式
|
||||
// dateTime.toLocal();
|
||||
final DateFormat formatter = DateFormat('yyyy-MM-dd HH:mm');
|
||||
// 返回格式化后的字符串
|
||||
return formatter.format(dateTime);
|
||||
}
|
||||
|
||||
static void scrollToFocusedInput(FocusNode focusNode, _scrollController) {
|
||||
// 获取输入框相对于整个页面的偏移量
|
||||
RenderObject? object = focusNode.context?.findRenderObject();
|
||||
if (object != null) {
|
||||
final RenderBox box = object as RenderBox;
|
||||
final Offset position = box.localToGlobal(Offset.zero);
|
||||
|
||||
// 将页面滚动到使输入框显示在屏幕上的位置
|
||||
_scrollController.animateTo(
|
||||
position.dy - MediaQuery.of(focusNode.context!).size.height / 4,
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void resetScrollPosition(_scrollController) {
|
||||
_scrollController.animateTo(
|
||||
initialScrollOffset,
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Color stringToColor(String hexColor) {
|
||||
String formattedColor = hexColor.replaceAll("#", "");
|
||||
int colorValue = int.parse("0xFF$formattedColor");
|
||||
return Color(colorValue);
|
||||
}
|
||||
|
||||
//字节转16进制
|
||||
String ab2str(List<int> buffer) {
|
||||
return buffer.map((x) => x.toRadixString(16).padLeft(2, '0')).join('');
|
||||
}
|
||||
|
||||
enum ToastColor { success, error, warn }
|
||||
|
||||
ToastColor color_success = ToastColor.success;
|
||||
ToastColor color_warning = ToastColor.warn;
|
||||
ToastColor color_error = ToastColor.error;
|
||||
|
||||
showToast(String msg,
|
||||
{ToastColor color = ToastColor.error, int closeTime = 3}) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: msg,
|
||||
// toastLength: Toast.LENGTH_LONG,
|
||||
// gravity: ToastGravity.CENTER,
|
||||
// timeInSecForIosWeb: 1,
|
||||
// backgroundColor: color == null ? color_error : color,
|
||||
// textColor: Colors.white,
|
||||
// fontSize: 14.0,
|
||||
// );
|
||||
final context = Get.overlayContext; // 获取 Overlay 的上下文
|
||||
Color background = Colors.red;
|
||||
Color color_text = stringToColor("#FA5A4C");
|
||||
String icon = "";
|
||||
if (color == color_success) {
|
||||
background = stringToColor("#DBF1E1");
|
||||
icon = "success";
|
||||
color_text = stringToColor("#31CA79");
|
||||
} else if (color == color_warning) {
|
||||
background = stringToColor("#FDF6EC");
|
||||
icon = "warn";
|
||||
color_text = stringToColor("#F8AE00");
|
||||
} else if (color == color_error) {
|
||||
background = stringToColor("#FEF0F0");
|
||||
icon = "error";
|
||||
color_text = stringToColor("#FA5A4C");
|
||||
}
|
||||
if (context == null) return;
|
||||
OverlayEntry overlayEntry = OverlayEntry(
|
||||
builder: (context) => Positioned(
|
||||
top: MediaQuery.of(context).size.height * 0.10,
|
||||
left: MediaQuery.of(context).size.width * 0.5 - 225.rpx,
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: Container(
|
||||
width: 450.rpx,
|
||||
padding: EdgeInsets.only(top: 20.rpx, bottom: 20.rpx),
|
||||
decoration: BoxDecoration(
|
||||
color: background,
|
||||
borderRadius: BorderRadius.circular(10.rpx),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/toast/${icon}_.png",
|
||||
width: 30.rpx,
|
||||
height: 30.rpx,
|
||||
),
|
||||
SizedBox(
|
||||
width: 18.rpx,
|
||||
),
|
||||
Container(
|
||||
constraints: BoxConstraints(maxWidth: 380.rpx),
|
||||
child: Text(
|
||||
msg,
|
||||
maxLines: 9,
|
||||
style: TextStyle(
|
||||
color: color_text,
|
||||
fontSize: 28.rpx,
|
||||
fontWeight: FontWeight.w400),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
Overlay.of(context)?.insert(overlayEntry);
|
||||
Future.delayed(Duration(seconds: closeTime), () {
|
||||
overlayEntry.remove();
|
||||
});
|
||||
}
|
||||
|
||||
var closeIcon = GestureDetector(
|
||||
onTapDown: (f) {
|
||||
Get.back();
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(10.rpx, 18.rpx, 10.rpx, 10.rpx),
|
||||
child: Container(
|
||||
height: 42.rpx,
|
||||
width: 42.rpx,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
var closeIconWhite = GestureDetector(
|
||||
onTapDown: (f) {
|
||||
Get.back();
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10.rpx),
|
||||
child: Container(
|
||||
height: 42.rpx,
|
||||
width: 42.rpx,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
var returnIconButtom = IconButton(
|
||||
// padding: EdgeInsets.zero, // 去除默认 padding
|
||||
// constraints: BoxConstraints(), // 去除最小尺寸限制
|
||||
onPressed: () => Get.back(),
|
||||
icon: Icon(Icons.navigate_before, size: 60.rpx),
|
||||
);
|
||||
|
||||
var returnIconButtomAddCallback = (returnCallBack) {
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
returnCallBack?.call();
|
||||
Get.back();
|
||||
},
|
||||
icon: Icon(Icons.navigate_before, size: 60.rpx),
|
||||
);
|
||||
};
|
||||
|
||||
String time_08_Formatter(String time) {
|
||||
if (time == null || time == "") {
|
||||
return "";
|
||||
}
|
||||
return DateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
.format(DateTime.parse(time).toLocal());
|
||||
}
|
||||
|
||||
String time_08_Formatter_pattern(String time, String pattern) {
|
||||
if (time == null || time == "") {
|
||||
return "";
|
||||
}
|
||||
return DateFormat(pattern).format(DateTime.parse(time).toLocal());
|
||||
}
|
||||
|
||||
String storagePubSrc =
|
||||
"${CommonVariables.supabaseUrl}/storage/v1/object/public/";
|
||||
|
||||
getStorageResourceUrl(String v) {
|
||||
if (v.contains('http')) {
|
||||
return v;
|
||||
}
|
||||
return storagePubSrc + v;
|
||||
}
|
||||
|
||||
enum LoadingDialogIcon { ble, wifi, none }
|
||||
|
||||
class LoadingDialog {
|
||||
static show(String name, {LoadingDialogIcon icon = LoadingDialogIcon.none}) {
|
||||
String iconUrl = "";
|
||||
if (icon == LoadingDialogIcon.wifi) {
|
||||
iconUrl = "wifi";
|
||||
} else if (icon == LoadingDialogIcon.ble) {
|
||||
iconUrl = "ble";
|
||||
}
|
||||
Get.dialog(
|
||||
PopScope(
|
||||
canPop: false,
|
||||
child: Container(
|
||||
// color: Colors.transparent,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
constraints:
|
||||
BoxConstraints(minWidth: 300.rpx, maxWidth: 500.rpx),
|
||||
decoration:
|
||||
BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (iconUrl.isNotEmpty)
|
||||
Container(
|
||||
width: 120.rpx,
|
||||
height: 120.rpx,
|
||||
margin: EdgeInsets.only(bottom: 60.rpx),
|
||||
child:
|
||||
Image.asset("assets/images/toast/${iconUrl}.png"),
|
||||
),
|
||||
Text(
|
||||
textAlign: TextAlign.center,
|
||||
name,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30.rpx,
|
||||
),
|
||||
const CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: false,
|
||||
barrierColor: Color.fromRGBO(0, 0, 0, 0.8));
|
||||
}
|
||||
|
||||
static hide() {
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
113
lib/common/util/Websocket.dart
Normal file
113
lib/common/util/Websocket.dart
Normal file
@@ -0,0 +1,113 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
import 'package:web_socket_channel/io.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
class WebsocketProp {
|
||||
late WebSocketChannel channel;
|
||||
bool isConnecting = false;
|
||||
bool isOpen = false;
|
||||
bool isClose = false; //是否关闭
|
||||
late String url;
|
||||
late Map fun;
|
||||
|
||||
WebsocketProp initState(String url_, Map funn) {
|
||||
print(url_);
|
||||
fun = funn;
|
||||
url = url_;
|
||||
isConnecting = false;
|
||||
_connect();
|
||||
return this;
|
||||
}
|
||||
|
||||
void _connect() {
|
||||
isOpen = false;
|
||||
channel = IOWebSocketChannel.connect(
|
||||
"$url?token=${Get.find<UserInfoController>().model.token}");
|
||||
channel.stream.listen((message) {
|
||||
// print('Received message: $message');
|
||||
// Handle incoming messages here
|
||||
heartCheck();
|
||||
if (isOpen == false) {
|
||||
fun['open']?.call();
|
||||
print('Received message: $message');
|
||||
isOpen = true;
|
||||
isConnecting = false;
|
||||
// Get.find<BedController>().websocketSend(1);
|
||||
return;
|
||||
}
|
||||
if (message == "ht") {
|
||||
print('Received message: $message');
|
||||
return;
|
||||
}
|
||||
fun["message"]?.call(message);
|
||||
}, onError: (error) {
|
||||
// Handle connection error and initiate reconnection
|
||||
print('Error: $error');
|
||||
isOpen = false;
|
||||
_reconnect();
|
||||
}, onDone: () {
|
||||
// Handle connection closed
|
||||
print('Connection closed');
|
||||
isOpen = false;
|
||||
_reconnect();
|
||||
});
|
||||
}
|
||||
|
||||
Timer? timeoutObj;
|
||||
Timer? serverTimeoutObj;
|
||||
int timeout = 10;
|
||||
|
||||
void heartCheck() {
|
||||
timeoutObj?.cancel();
|
||||
serverTimeoutObj?.cancel();
|
||||
timeoutObj = Timer(Duration(seconds: timeout), () {
|
||||
sendMessage("ht");
|
||||
serverTimeoutObj = Timer(Duration(seconds: timeout), () {
|
||||
dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _reconnect() {
|
||||
if (isClose) {
|
||||
return;
|
||||
}
|
||||
if (!isConnecting) {
|
||||
isConnecting = true;
|
||||
_connect();
|
||||
Timer(const Duration(seconds: 5), () {
|
||||
isConnecting = false;
|
||||
if (isOpen == false) {
|
||||
_reconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void sendMessage(data) {
|
||||
if (isOpen == false) {
|
||||
// showToast("websocket 已断开");
|
||||
return;
|
||||
}
|
||||
if (data is String) {
|
||||
channel.sink.add(data);
|
||||
} else {
|
||||
String s = jsonEncode(data);
|
||||
// print("发送 $s");
|
||||
channel.sink.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
sendWebSocketMessageCodeN(code, data) {
|
||||
sendMessage({"code": code, "data": data});
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
isClose = true;
|
||||
channel.sink.close();
|
||||
}
|
||||
}
|
||||
86
lib/common/util/myDialog/MyDialog.dart
Normal file
86
lib/common/util/myDialog/MyDialog.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'my_dialog_controller.dart';
|
||||
|
||||
class MyDialog extends GetView<MyDialogController> {
|
||||
final String message;
|
||||
final int seconds;
|
||||
final Color? textColor; // 可选参数
|
||||
|
||||
MyDialog({
|
||||
required this.message,
|
||||
required this.seconds,
|
||||
this.textColor, // 可选参数的赋值
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 设置弹窗在2秒后自动关闭
|
||||
Timer(Duration(seconds: seconds), () {
|
||||
if (Navigator.canPop(context)) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
});
|
||||
|
||||
return Dialog(
|
||||
backgroundColor: Colors.transparent, // 使弹窗背景透明
|
||||
elevation: 0, // 去除阴影
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 232,
|
||||
maxHeight: 400,
|
||||
minHeight: 47,
|
||||
maxWidth: 400,
|
||||
),
|
||||
child: Opacity(
|
||||
opacity: 1, // 设置容器的透明度为80%
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: Color(0xFF182B7C),
|
||||
color: Color(0xFFffebe9),
|
||||
border: Border.all(
|
||||
// color: Color(0xFFe60012), // 边框颜色
|
||||
color: textColor ?? Color(0xFFe60012),
|
||||
width: 1, // 边框宽度
|
||||
),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black26,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
// color: Color(0xFFe60012), // 边框颜色
|
||||
color: textColor ?? Color(0xFFe60012),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
71
lib/common/util/myDialog/confirm_dialog.dart
Normal file
71
lib/common/util/myDialog/confirm_dialog.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
|
||||
class ConfirmDialog extends GetView {
|
||||
ConfirmDialog();
|
||||
|
||||
Future showConfirmCustomDialog(BuildContext context,
|
||||
{String name = "是否确认取消?"}) async {
|
||||
// Completer<String> completer = Completer<String>();
|
||||
TextEditingController textEditingController = TextEditingController();
|
||||
return showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
child: Container(
|
||||
width: 340,
|
||||
padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(alignment: Alignment.centerRight, child: closeIcon),
|
||||
Center(
|
||||
child: Text(
|
||||
'${name}',
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 50.rpx, bottom: 40.rpx),
|
||||
alignment: Alignment.center,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Get.back(result: "confirm");
|
||||
},
|
||||
child: Container(
|
||||
width: 280.rpx,
|
||||
height: 60.rpx,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: stringToColor("#D3B684")),
|
||||
child: Text(
|
||||
'确定',
|
||||
style: TextStyle(color: Colors.white, fontSize: 30.rpx),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
// return completer.future;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// TODO: implement build
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
44
lib/common/util/myDialog/my_dialog_controller.dart
Normal file
44
lib/common/util/myDialog/my_dialog_controller.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'MyDialog.dart';
|
||||
|
||||
part 'my_dialog_controller.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class MyDialogModel {
|
||||
//版本id
|
||||
String? title_name = "标题"; //标题
|
||||
String? message = "消息内容";
|
||||
|
||||
MyDialogModel();
|
||||
|
||||
static MyDialogModel fromJson(Map<String, dynamic> json) =>
|
||||
_$MyDialogModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$MyDialogModelToJson(this);
|
||||
}
|
||||
|
||||
class MyDialogController extends GetControllerEx<MyDialogModel> {
|
||||
MyDialogController() {
|
||||
attr = GetModel(MyDialogModel()).obs;
|
||||
}
|
||||
|
||||
Future<void> showCustomDialog(
|
||||
BuildContext context,
|
||||
String message, {
|
||||
Color? textColor, // 可选参数
|
||||
}) async {
|
||||
await showDialog(
|
||||
barrierColor: Colors.transparent, // 设置上级页面不变暗
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return MyDialog(
|
||||
message: message,
|
||||
seconds: 2,
|
||||
textColor: textColor,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
18
lib/common/util/myDialog/my_dialog_controller.g.dart
Normal file
18
lib/common/util/myDialog/my_dialog_controller.g.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'my_dialog_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MyDialogModel _$MyDialogModelFromJson(Map<String, dynamic> json) =>
|
||||
MyDialogModel()
|
||||
..title_name = json['title_name'] as String?
|
||||
..message = json['message'] as String?;
|
||||
|
||||
Map<String, dynamic> _$MyDialogModelToJson(MyDialogModel instance) =>
|
||||
<String, dynamic>{
|
||||
'title_name': instance.title_name,
|
||||
'message': instance.message,
|
||||
};
|
||||
95
lib/component/tool/CustomCard.dart
Normal file
95
lib/component/tool/CustomCard.dart
Normal file
@@ -0,0 +1,95 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomCard extends StatefulWidget {
|
||||
final double borderRadius; // 圆角
|
||||
final VoidCallback onTap; // 点击回调
|
||||
final List<Color> colors; // 背景颜色列表
|
||||
final Widget child; // 子组件
|
||||
final String title;
|
||||
|
||||
const CustomCard({
|
||||
Key? key,
|
||||
required this.borderRadius,
|
||||
required this.onTap,
|
||||
required this.colors,
|
||||
required this.child,
|
||||
required this.title,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<CustomCard> createState() => _CustomCardState();
|
||||
}
|
||||
|
||||
class _CustomCardState extends State<CustomCard>
|
||||
with SingleTickerProviderStateMixin {
|
||||
double _scale = 1.0;
|
||||
final Duration _animationDuration = Duration(milliseconds: 50);
|
||||
final GlobalKey _inkKey = GlobalKey();
|
||||
|
||||
Future<void> _handleTap(TapDownDetails details) async {
|
||||
setState(() {
|
||||
_scale = 0.95;
|
||||
});
|
||||
|
||||
await Future.delayed(_animationDuration);
|
||||
|
||||
setState(() {
|
||||
_scale = 1.0;
|
||||
});
|
||||
|
||||
await Future.delayed(_animationDuration);
|
||||
|
||||
// 手动触发水波纹
|
||||
final RenderBox? box =
|
||||
_inkKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
if (box != null) {
|
||||
final Offset localPosition = box.globalToLocal(details.globalPosition);
|
||||
InkRipple.splashFactory.create(
|
||||
controller: Material.of(_inkKey.currentContext!)!,
|
||||
referenceBox: box,
|
||||
position: localPosition,
|
||||
color: widget.colors.first.withOpacity(0.2),
|
||||
containedInkWell: true,
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
textDirection: Directionality.of(context),
|
||||
);
|
||||
}
|
||||
|
||||
widget.onTap();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bool isGradient = widget.colors.length > 1;
|
||||
final Color baseColor = widget.colors.first;
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
child: GestureDetector(
|
||||
onTapDown: _handleTap,
|
||||
behavior: HitTestBehavior.translucent, // 关键:让空白区域也能点击
|
||||
child: AnimatedScale(
|
||||
scale: _scale,
|
||||
duration: _animationDuration,
|
||||
curve: Curves.easeInOut,
|
||||
child: Ink(
|
||||
key: _inkKey,
|
||||
decoration: BoxDecoration(
|
||||
color: isGradient ? null : baseColor,
|
||||
gradient: isGradient
|
||||
? LinearGradient(
|
||||
colors: widget.colors,
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(widget.borderRadius),
|
||||
),
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
31
lib/controller/device/blueteeth_bind_controller.dart
Normal file
31
lib/controller/device/blueteeth_bind_controller.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'blueteeth_bind_controller.g.dart'; // 由json_serializable自动生成的部分
|
||||
|
||||
@JsonSerializable()
|
||||
class BlueteethBindModel {
|
||||
int read = 1;//是否不再提示教程 0 不再提示 1 需要提示
|
||||
|
||||
BlueteethBindModel();
|
||||
|
||||
// 从JSON反序列化时的异常处理
|
||||
|
||||
factory BlueteethBindModel.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
return _$BlueteethBindModelFromJson(json);
|
||||
} catch (e) {
|
||||
// 在实际应用中,应该有更细致的异常处理策略和错误日志
|
||||
return BlueteethBindModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
|
||||
}
|
||||
}
|
||||
|
||||
// 序列化为JSON时的异常处理
|
||||
Map<String, dynamic> toJson() => _$BlueteethBindModelToJson(this);
|
||||
}
|
||||
|
||||
class BlueteethBindController extends GetControllerEx<BlueteethBindModel> {
|
||||
BlueteethBindController() {
|
||||
attr = GetModel(BlueteethBindModel()).obs;
|
||||
}
|
||||
}
|
||||
15
lib/controller/device/blueteeth_bind_controller.g.dart
Normal file
15
lib/controller/device/blueteeth_bind_controller.g.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'blueteeth_bind_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BlueteethBindModel _$BlueteethBindModelFromJson(Map<String, dynamic> json) =>
|
||||
BlueteethBindModel()..read = (json['read'] as num).toInt();
|
||||
|
||||
Map<String, dynamic> _$BlueteethBindModelToJson(BlueteethBindModel instance) =>
|
||||
<String, dynamic>{
|
||||
'read': instance.read,
|
||||
};
|
||||
172
lib/controller/main_bottom/global_controller.dart
Normal file
172
lib/controller/main_bottom/global_controller.dart
Normal file
@@ -0,0 +1,172 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class GlobalModel {
|
||||
List deviceList = [];
|
||||
Map deviceMain = {};
|
||||
|
||||
Map useBedController = {}; //之前控制的设备
|
||||
|
||||
List deviceType = [];
|
||||
|
||||
List homeImgList = []; //轮播图
|
||||
|
||||
bool hideBottomNavigationBar = false;
|
||||
|
||||
get deviceMainIsShare {
|
||||
if (deviceMain != null && deviceMain["type"] == 2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get JunheDevices {
|
||||
// List arr = [];
|
||||
|
||||
// deviceList.forEach((d) {
|
||||
// d?["personnelInfo"]?.forEach((item) {
|
||||
// if (item["mac"] == d["bindMacA"] &&
|
||||
// arr.indexWhere((a) => a["mac"] == item["mac"]) == -1) {
|
||||
// arr.add(item);
|
||||
// }
|
||||
// });
|
||||
// if (d["bindMacB"] != null && d["bindMacB"] != "") {
|
||||
// d["personnelInfo"].forEach((item) {
|
||||
// if (item["mac"] == d["bindMacB"] &&
|
||||
// arr.indexWhere((a) => a["mac"] == item["mac"]) == -1) {
|
||||
// arr.add(item);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// return arr;
|
||||
// }
|
||||
|
||||
get JunheDevices {
|
||||
List arr = [];
|
||||
try {
|
||||
if (deviceList != null) {
|
||||
deviceList.forEach((d) {
|
||||
if (d?["personnelInfo"] != null) {
|
||||
d["personnelInfo"].forEach((item) {
|
||||
if (item["mac"] == d["bindMacA"] &&
|
||||
arr.indexWhere((a) => a["mac"] == item["mac"]) == -1) {
|
||||
arr.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (d["bindMacB"] != null && d["bindMacB"] != "") {
|
||||
if (d["personnelInfo"] != null) {
|
||||
d["personnelInfo"].forEach((item) {
|
||||
if (item["mac"] == d["bindMacB"] &&
|
||||
arr.indexWhere((a) => a["mac"] == item["mac"]) == -1) {
|
||||
arr.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
get mainDevicePeople {
|
||||
if (deviceMain == null || deviceMain["mac"] == null) {
|
||||
return [{}, {}];
|
||||
}
|
||||
List arr = [{}, {}];
|
||||
if (deviceMain["personnelInfo"] != null) {
|
||||
if (deviceMain["bindMacA"] != null) {
|
||||
deviceMain["personnelInfo"]?.forEach((d) {
|
||||
if (d["mac"] == deviceMain["bindMacA"]) {
|
||||
arr[0] = d;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (deviceMain["bindMacB"] != null) {
|
||||
deviceMain["personnelInfo"]?.forEach((d) {
|
||||
if (d["mac"] == deviceMain["bindMacB"]) {
|
||||
arr[1] = d;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
GlobalModel();
|
||||
}
|
||||
|
||||
class GlobalController extends GetControllerEx<GlobalModel> {
|
||||
GlobalController() {
|
||||
attr = GetModel(GlobalModel()).obs;
|
||||
}
|
||||
|
||||
get userInfoController => Get.find<UserInfoController>();
|
||||
|
||||
Timer? getDeviceListTimer;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
resetParmAll() {
|
||||
resetParm();
|
||||
Get.find<MainPageController>().resetParm();
|
||||
}
|
||||
|
||||
resetParm() {
|
||||
getDeviceListTimer?.cancel();
|
||||
getDeviceListTimer = null;
|
||||
model.deviceList = [];
|
||||
model.deviceMain = {};
|
||||
model.useBedController = {};
|
||||
model.deviceType = [];
|
||||
model.homeImgList = [];
|
||||
model.hideBottomNavigationBar = false;
|
||||
}
|
||||
|
||||
deviceUpdateTimerCreated() {
|
||||
if (getDeviceListTimer == null) {
|
||||
getDeviceListTimer = Timer.periodic(const Duration(seconds: 10), (t) {
|
||||
if (userInfoController.model.token != null) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
getDeviceGroupName(device) {
|
||||
return "${device['roomName']}/${device["deviceType"]?["name"]}/${device["name"]}";
|
||||
}
|
||||
|
||||
getDeviceGroupName2(device) {
|
||||
return "${device["deviceType"]?["name"]}/${device["name"]}";
|
||||
}
|
||||
|
||||
getUpperCaseMac(mac) {
|
||||
if (mac == null || mac == "") {
|
||||
return "";
|
||||
}
|
||||
return "$mac".toUpperCase();
|
||||
}
|
||||
|
||||
getDeviceType() async {
|
||||
var rs =
|
||||
await ef.from("app_device_type").select().order("id", ascending: true);
|
||||
model.deviceType = rs.where((d) => d["page"] != null).toList();
|
||||
updateAll();
|
||||
}
|
||||
}
|
||||
34
lib/controller/main_bottom/main_page_controller.dart
Normal file
34
lib/controller/main_bottom/main_page_controller.dart
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'main_page_controller.g.dart'; // 由json_serializable自动生成的部分
|
||||
|
||||
@JsonSerializable()
|
||||
class MainPageModel {
|
||||
int currentIndex = 0;
|
||||
MainPageModel();
|
||||
|
||||
// 从JSON反序列化时的异常处理
|
||||
|
||||
factory MainPageModel.fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
return _$MainPageModelFromJson(json);
|
||||
} catch (e) {
|
||||
// 在实际应用中,应该有更细致的异常处理策略和错误日志
|
||||
return MainPageModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
|
||||
}
|
||||
}
|
||||
|
||||
// 序列化为JSON时的异常处理
|
||||
Map<String, dynamic> toJson() => _$MainPageModelToJson(this);
|
||||
}
|
||||
|
||||
class MainPageController extends GetControllerEx<MainPageModel> {
|
||||
MainPageController() {
|
||||
attr = GetModel(MainPageModel()).obs;
|
||||
}
|
||||
|
||||
resetParm() {
|
||||
model.currentIndex = 0;
|
||||
}
|
||||
}
|
||||
15
lib/controller/main_bottom/main_page_controller.g.dart
Normal file
15
lib/controller/main_bottom/main_page_controller.g.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'main_page_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MainPageModel _$MainPageModelFromJson(Map<String, dynamic> json) =>
|
||||
MainPageModel()..currentIndex = (json['currentIndex'] as num).toInt();
|
||||
|
||||
Map<String, dynamic> _$MainPageModelToJson(MainPageModel instance) =>
|
||||
<String, dynamic>{
|
||||
'currentIndex': instance.currentIndex,
|
||||
};
|
||||
18
lib/controller/theme_controller/ThemeController.dart
Normal file
18
lib/controller/theme_controller/ThemeController.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/model/CustomThemeColor.dart';
|
||||
|
||||
class ThemeController extends GetControllerEx {
|
||||
//todo 数据库查询的颜色等于这个
|
||||
CustomThemeColor currentColor = CustomThemeColor.light;
|
||||
ThemeData currentTheme = ThemeData();
|
||||
|
||||
void changeTheme(CustomThemeColor color) {
|
||||
currentColor = color;
|
||||
currentTheme = ThemeData(
|
||||
primaryColor: color.sc1,
|
||||
scaffoldBackgroundColor: color.sc2,
|
||||
);
|
||||
update();
|
||||
}
|
||||
}
|
||||
50
lib/controller/user_info_controller.dart
Normal file
50
lib/controller/user_info_controller.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:vbvs_app/common/color/app_uri_status.dart';
|
||||
import 'package:vbvs_app/common/util/CommonVariables.dart';
|
||||
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/model/api_response.dart';
|
||||
import 'package:vbvs_app/model/user_data.dart';
|
||||
|
||||
|
||||
part 'user_info_controller.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class UserInfoModel {
|
||||
int? message = 0; //消息数量
|
||||
|
||||
UserModel? user; //用户信息
|
||||
String? token; //token值
|
||||
String? runSystem; //运行系统
|
||||
String? phoneVersion; //手机版本
|
||||
String? deviceId; //手机唯一
|
||||
String? deviceModel; //设备可见型号(如 "iPhone","iPad")
|
||||
String? appVersion; //app版本信息
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
Session? superbase_session;
|
||||
@JsonKey(ignore: true)
|
||||
User? superbase_user;
|
||||
|
||||
String? img_bucket = 'user';
|
||||
int? login = 0; //是否登录0:未登录 1:已登录
|
||||
|
||||
UserInfoModel();
|
||||
static UserInfoModel fromJson(Map<String, dynamic> json) =>
|
||||
_$UserInfoModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$UserInfoModelToJson(this);
|
||||
}
|
||||
|
||||
class UserInfoController extends GetControllerEx<UserInfoModel> {
|
||||
// 初始化实例
|
||||
UserInfoController() {
|
||||
attr = GetModel(UserInfoModel()).obs;
|
||||
}
|
||||
}
|
||||
36
lib/controller/user_info_controller.g.dart
Normal file
36
lib/controller/user_info_controller.g.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'user_info_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
UserInfoModel _$UserInfoModelFromJson(Map<String, dynamic> json) =>
|
||||
UserInfoModel()
|
||||
..message = (json['message'] as num?)?.toInt()
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: UserModel.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..token = json['token'] as String?
|
||||
..runSystem = json['runSystem'] as String?
|
||||
..phoneVersion = json['phoneVersion'] as String?
|
||||
..deviceId = json['deviceId'] as String?
|
||||
..deviceModel = json['deviceModel'] as String?
|
||||
..appVersion = json['appVersion'] as String?
|
||||
..img_bucket = json['img_bucket'] as String?
|
||||
..login = (json['login'] as num?)?.toInt();
|
||||
|
||||
Map<String, dynamic> _$UserInfoModelToJson(UserInfoModel instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message,
|
||||
'user': instance.user,
|
||||
'token': instance.token,
|
||||
'runSystem': instance.runSystem,
|
||||
'phoneVersion': instance.phoneVersion,
|
||||
'deviceId': instance.deviceId,
|
||||
'deviceModel': instance.deviceModel,
|
||||
'appVersion': instance.appVersion,
|
||||
'img_bucket': instance.img_bucket,
|
||||
'login': instance.login,
|
||||
};
|
||||
63
lib/language/AppLanguage.dart
Normal file
63
lib/language/AppLanguage.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppLanguage extends Translations {
|
||||
// 私有构造函数
|
||||
AppLanguage._internal();
|
||||
|
||||
// 单例实例
|
||||
static final AppLanguage _instance = AppLanguage._internal();
|
||||
|
||||
factory AppLanguage() => _instance;
|
||||
|
||||
// 缓存翻译数据
|
||||
final Map<String, Map<String, String>> _localizedValues = {};
|
||||
|
||||
@override
|
||||
Map<String, Map<String, String>> get keys => _localizedValues;
|
||||
|
||||
// 动态加载语言文件
|
||||
Future<void> loadLanguage(String languageCode) async {
|
||||
if (_localizedValues.containsKey(languageCode)) {
|
||||
return; // 如果语言已经加载,无需重复加载
|
||||
}
|
||||
|
||||
try {
|
||||
// 加载 JSON 文件
|
||||
final jsonString =
|
||||
await rootBundle.loadString('assets/langs/$languageCode.json');
|
||||
final Map<String, dynamic> jsonMap = json.decode(jsonString);
|
||||
|
||||
// 扁平化 JSON 数据并存储到缓存
|
||||
_localizedValues[languageCode] = _flattenJson(jsonMap);
|
||||
|
||||
// 通知 GetX 更新 keys
|
||||
// Get.forceAppUpdate();
|
||||
Get.appendTranslations(keys);
|
||||
} catch (e) {
|
||||
print('Error loading $languageCode language file: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 扁平化嵌套 JSON 数据
|
||||
Map<String, String> _flattenJson(Map<String, dynamic> json,
|
||||
[String prefix = '']) {
|
||||
final Map<String, String> flatMap = {};
|
||||
json.forEach((key, value) {
|
||||
final newKey = prefix.isEmpty ? key : '$prefix.$key';
|
||||
if (value is Map<String, dynamic>) {
|
||||
flatMap.addAll(_flattenJson(value, newKey));
|
||||
} else {
|
||||
flatMap[newKey] = value.toString();
|
||||
}
|
||||
});
|
||||
return flatMap;
|
||||
}
|
||||
|
||||
// 清理语言缓存
|
||||
void clearLanguage(String languageCode) {
|
||||
_localizedValues.remove(languageCode);
|
||||
}
|
||||
}
|
||||
262
lib/main.dart
262
lib/main.dart
@@ -1,125 +1,161 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get_storage/get_storage.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
|
||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||
import 'package:vbvs_app/language/AppLanguage.dart';
|
||||
import 'package:vbvs_app/model/CustomThemeColor.dart';
|
||||
import 'package:vbvs_app/model/user_data.dart';
|
||||
import 'controller/user_info_controller.dart';
|
||||
import 'routers/routers.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await AppLanguage().loadLanguage("zh_CN");
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// ApiService.init();
|
||||
// await GetStorage.init();
|
||||
// 初始化登录
|
||||
await initLogin();
|
||||
// 检查网络
|
||||
// Checknetwork.checkNetwork();
|
||||
// 微信开放平台注册
|
||||
// initWX();
|
||||
// // 初始化 flutter_xupdate android app 更新
|
||||
// initXUpdate();
|
||||
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
|
||||
.then((_) {
|
||||
runApp(MyApp());
|
||||
});
|
||||
|
||||
// runApp(const MyApp());
|
||||
}
|
||||
|
||||
Future<void> initLogin() async {
|
||||
// 初始化控制器
|
||||
Get.put(UserInfoController());
|
||||
// Get.put(SettingController());
|
||||
|
||||
// 获取设备信息,需要用户点击确认隐私协议与用户协议选择框时才能获取
|
||||
// Deviceconfig.initPlatformState();
|
||||
// 获取app版本号
|
||||
// SettingController settingController = Get.find();
|
||||
// settingController.model.appVersion = await Deviceconfig.getAppVersion();
|
||||
|
||||
final box = GetStorage();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
String? token = box.read('token');
|
||||
// print('Token: $token');
|
||||
Map<String, dynamic>? userMap = box.read('user');
|
||||
if (userMap != null) {
|
||||
UserModel user = UserModel.fromJson(userMap);
|
||||
userInfoController.model.user = user;
|
||||
}
|
||||
if (token != null) {
|
||||
// userInfoController.model.login = 1;
|
||||
//根据token去请求
|
||||
// await userInfoController.autoLogin(token);
|
||||
} else {
|
||||
// 如果没有 token,则将用户标记为未登录
|
||||
userInfoController.model.login = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化微信开放平台注册
|
||||
// Future<void> initWX() async {
|
||||
// Fluwx fluwx = Fluwx();
|
||||
// fluwx.registerApi(
|
||||
// //请填写自己的微信appid
|
||||
// appId: "wx929c548fea6af9c7",
|
||||
// doOnAndroid: true,
|
||||
// doOnIOS: true,
|
||||
// universalLink: "https://zhmht.swes.com.cn/app/");
|
||||
// }
|
||||
|
||||
// // 初始化 flutter_xupdate android app 更新
|
||||
// Future<void> initXUpdate() async {
|
||||
// if (Platform.isAndroid) {
|
||||
// FlutterXUpdate.init(
|
||||
// // 是否输出日志
|
||||
// debug: true,
|
||||
// // 是否使用post请求
|
||||
// isPost: true,
|
||||
// // post请求是否是上传json
|
||||
// isPostJson: false,
|
||||
// // 请求响应超时时间
|
||||
// timeout: 25000,
|
||||
// // 是否开启自动模式
|
||||
// isWifiOnly: false,
|
||||
// // 是否开启自动模式
|
||||
// isAutoMode: false,
|
||||
// // 需要设置的公共参数
|
||||
// supportSilentInstall: false,
|
||||
// // 在下载过程中,如果点击了取消的话,是否弹出切换下载方式的重试提示弹窗
|
||||
// enableRetry: false)
|
||||
// .then((value) {
|
||||
// print('初始化成功: $value');
|
||||
// }).catchError((error) {
|
||||
// print(error);
|
||||
// });
|
||||
|
||||
// FlutterXUpdate.setUpdateHandler(onUpdateError: (message) async {
|
||||
// print('onUpdateError: $message');
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
MyApp({super.key});
|
||||
final ThemeController themeController = Get.put(ThemeController());
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
theme: ThemeData(
|
||||
// This is the theme of your application.
|
||||
//
|
||||
// TRY THIS: Try running your application with "flutter run". You'll see
|
||||
// the application has a purple toolbar. Then, without quitting the app,
|
||||
// try changing the seedColor in the colorScheme below to Colors.green
|
||||
// and then invoke "hot reload" (save your changes or press the "hot
|
||||
// reload" button in a Flutter-supported IDE, or press "r" if you used
|
||||
// the command line to start the app).
|
||||
//
|
||||
// Notice that the counter didn't reset back to zero; the application
|
||||
// state is not lost during the reload. To reset the state, use hot
|
||||
// restart instead.
|
||||
//
|
||||
// This works for code too, not just values: Most code changes can be
|
||||
// tested with just a hot reload.
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({super.key, required this.title});
|
||||
|
||||
// This widget is the home page of your application. It is stateful, meaning
|
||||
// that it has a State object (defined below) that contains fields that affect
|
||||
// how it looks.
|
||||
|
||||
// This class is the configuration for the state. It holds the values (in this
|
||||
// case the title) provided by the parent (in this case the App widget) and
|
||||
// used by the build method of the State. Fields in a Widget subclass are
|
||||
// always marked "final".
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
int _counter = 0;
|
||||
|
||||
void _incrementCounter() {
|
||||
setState(() {
|
||||
// This call to setState tells the Flutter framework that something has
|
||||
// changed in this State, which causes it to rerun the build method below
|
||||
// so that the display can reflect the updated values. If we changed
|
||||
// _counter without calling setState(), then the build method would not be
|
||||
// called again, and so nothing would appear to happen.
|
||||
_counter++;
|
||||
themeController.changeTheme(CustomThemeColor.dark);
|
||||
UserInfoController userInfoController = Get.find();
|
||||
return LayoutBuilder(builder: (contxt, cons) {
|
||||
double width = cons.maxWidth;
|
||||
double height = cons.maxHeight;
|
||||
if (width < 1) {
|
||||
return Container();
|
||||
}
|
||||
FitTool.init(width < height ? width : height);
|
||||
return GetMaterialApp(
|
||||
translations: AppLanguage(),
|
||||
locale: const Locale("zh", "CN"),
|
||||
fallbackLocale: const Locale("zh", "CN"),
|
||||
localizationsDelegates: [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
SfGlobalLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [
|
||||
const Locale('zh', 'CN'), // 中文
|
||||
// 其他支持的语言
|
||||
],
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: '',
|
||||
theme: themeController.currentTheme,
|
||||
// home: const MyHomePage(title: '智慧眠花糖 Home Page'),
|
||||
initialRoute: "/mianPageBottomChange",
|
||||
onGenerateRoute: onGenerateRoute,
|
||||
initialBinding: BindingsBuilder(() => [
|
||||
Get.lazyPut(() => UserInfoController()),
|
||||
Get.put(GlobalController()),
|
||||
Get.lazyPut(() => MainPageController()),
|
||||
Get.lazyPut(() => BlueteethBindController()),
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// This method is rerun every time setState is called, for instance as done
|
||||
// by the _incrementCounter method above.
|
||||
//
|
||||
// The Flutter framework has been optimized to make rerunning build methods
|
||||
// fast, so that you can just rebuild anything that needs updating rather
|
||||
// than having to individually change instances of widgets.
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
// TRY THIS: Try changing the color here to a specific color (to
|
||||
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
|
||||
// change color while the other colors stay the same.
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
// Here we take the value from the MyHomePage object that was created by
|
||||
// the App.build method, and use it to set our appbar title.
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: Center(
|
||||
// Center is a layout widget. It takes a single child and positions it
|
||||
// in the middle of the parent.
|
||||
child: Column(
|
||||
// Column is also a layout widget. It takes a list of children and
|
||||
// arranges them vertically. By default, it sizes itself to fit its
|
||||
// children horizontally, and tries to be as tall as its parent.
|
||||
//
|
||||
// Column has various properties to control how it sizes itself and
|
||||
// how it positions its children. Here we use mainAxisAlignment to
|
||||
// center the children vertically; the main axis here is the vertical
|
||||
// axis because Columns are vertical (the cross axis would be
|
||||
// horizontal).
|
||||
//
|
||||
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
|
||||
// action in the IDE, or press "p" in the console), to see the
|
||||
// wireframe for each widget.
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
const Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _incrementCounter,
|
||||
tooltip: 'Increment',
|
||||
child: const Icon(Icons.add),
|
||||
), // This trailing comma makes auto-formatting nicer for build methods.
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
283
lib/model/CustomThemeColor.dart
Normal file
283
lib/model/CustomThemeColor.dart
Normal file
@@ -0,0 +1,283 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class CustomThemeColor {
|
||||
final String color1;//
|
||||
final String color2;
|
||||
final String color3;
|
||||
final String color4;
|
||||
final String color5;
|
||||
final String color6;
|
||||
final String color7;
|
||||
final String color8;
|
||||
final String color9;
|
||||
final String color10;
|
||||
final String color11;
|
||||
final String color12;
|
||||
final String color13;
|
||||
final String color14;
|
||||
final String color15;
|
||||
final String color16;
|
||||
final String color17;
|
||||
final String color18;
|
||||
final String color19;
|
||||
final String color20;
|
||||
final String color21;
|
||||
final String color25;
|
||||
final String color26;
|
||||
final String color27;
|
||||
final String color28;
|
||||
final String color29;
|
||||
final String color30;
|
||||
final String color31;
|
||||
final String color32;
|
||||
final String color33;
|
||||
final String color34;
|
||||
|
||||
final String color38;
|
||||
final String color39;
|
||||
final String color40;
|
||||
|
||||
CustomThemeColor({
|
||||
required this.color1,
|
||||
required this.color2,
|
||||
required this.color3,
|
||||
required this.color4,
|
||||
required this.color5,
|
||||
required this.color6,
|
||||
required this.color7,
|
||||
required this.color8,
|
||||
required this.color9,
|
||||
required this.color10,
|
||||
required this.color11,
|
||||
required this.color12,
|
||||
required this.color13,
|
||||
required this.color14,
|
||||
required this.color15,
|
||||
required this.color16,
|
||||
required this.color17,
|
||||
required this.color18,
|
||||
required this.color19,
|
||||
required this.color20,
|
||||
required this.color21,
|
||||
required this.color25,
|
||||
required this.color26,
|
||||
required this.color27,
|
||||
required this.color28,
|
||||
required this.color29,
|
||||
required this.color30,
|
||||
required this.color31,
|
||||
required this.color32,
|
||||
required this.color33,
|
||||
required this.color34,
|
||||
required this.color38,
|
||||
required this.color39,
|
||||
required this.color40,
|
||||
});
|
||||
|
||||
//浅色模式
|
||||
static final light = CustomThemeColor(
|
||||
color1: '#FFFFFF',
|
||||
color2: "#f7f8fa",
|
||||
color3: "#4AD8FA",
|
||||
color4: "#4AD8FA",
|
||||
color5: "#4AD8FA",
|
||||
color6: "#4AD8FA",
|
||||
color7: "#333333",
|
||||
color8: "#333333",
|
||||
color9: "#333333",
|
||||
color10: "#f7f8fa",
|
||||
color11: "#f7f8fa",
|
||||
color12: "#DBF8FD",
|
||||
color13: "#d3d3d3",
|
||||
color14: "#333333",
|
||||
color15: "#FF7159",
|
||||
color16: "#d3d3d3",
|
||||
color17: "#FFFFFF",
|
||||
color18: "#4AD8FA",
|
||||
color19: "#4AD8FA",
|
||||
color20: "#f7f8fa",
|
||||
color21: "#5EE00A",
|
||||
color25: "#FF7159",
|
||||
color26: "#4AD8FA",
|
||||
color27: "#f7f8fa",
|
||||
color28: "#4E8408",
|
||||
color29: "#79BC31",
|
||||
color30: "#E55E92",
|
||||
color31: "#FF1D25",
|
||||
color32: "#7bbb33",
|
||||
color33: "#fe15b8d",
|
||||
color34: "#EE0000",
|
||||
color38: "#E3E4E5",
|
||||
color39: "#F3F5F6",
|
||||
color40: "#333333");
|
||||
//深色模式
|
||||
static final dark = CustomThemeColor(
|
||||
color1: '#242835',
|
||||
color2: "#f7f8fa",
|
||||
color3: "#4AD8FA",
|
||||
color4: "#4AD8FA",
|
||||
color5: "#4AD8FA",
|
||||
color6: "#4AD8FA",
|
||||
color7: "#333333",
|
||||
color8: "#333333",
|
||||
color9: "#333333",
|
||||
color10: "#f7f8fa",
|
||||
color11: "#f7f8fa",
|
||||
color12: "#DBF8FD",
|
||||
color13: "#d3d3d3",
|
||||
color14: "#333333",
|
||||
color15: "#FF7159",
|
||||
color16: "#d3d3d3",
|
||||
color17: "#FFFFFF",
|
||||
color18: "#4AD8FA",
|
||||
color19: "#4AD8FA",
|
||||
color20: "#f7f8fa",
|
||||
color21: "#5EE00A",
|
||||
color25: "#FF7159",
|
||||
color26: "#4AD8FA",
|
||||
color27: "#f7f8fa",
|
||||
color28: "#4E8408",
|
||||
color29: "#79BC31",
|
||||
color30: "#E55E92",
|
||||
color31: "#FF1D25",
|
||||
color32: "#7bbb33",
|
||||
color33: "#fe15b8d",
|
||||
color34: "#EE0000",
|
||||
color38: "#E3E4E5",
|
||||
color39: "#F3F5F6",
|
||||
color40: "#333333");
|
||||
|
||||
//获取颜色1 菜单栏颜色
|
||||
Color get sc1 => getColor(color1);
|
||||
//获取颜色2
|
||||
Color get sc2 => getColor(color2);
|
||||
//获取颜色3
|
||||
Color get sc3 => getColor(color3);
|
||||
//获取颜色4
|
||||
Color get sc4 => getColor(color4);
|
||||
//获取颜色5
|
||||
Color get sc5 => getColor(color5);
|
||||
//获取颜色6
|
||||
Color get sc6 => getColor(color6);
|
||||
//获取颜色7
|
||||
Color get sc7 => getColor(color7);
|
||||
//获取颜色8
|
||||
Color get sc8 => getColor(color8);
|
||||
//获取颜色9
|
||||
Color get sc9 => getColor(color9);
|
||||
//获取颜色10
|
||||
Color get sc10 => getColor(color10);
|
||||
Color get sc11 => getColor(color11);
|
||||
Color get sc12 => getColor(color12);
|
||||
Color get sc13 => getColor(color13);
|
||||
Color get sc14 => getColor(color14);
|
||||
Color get sc15 => getColor(color15);
|
||||
Color get sc16 => getColor(color16);
|
||||
Color get sc17 => getColor(color17);
|
||||
Color get sc18 => getColor(color18);
|
||||
Color get sc19 => getColor(color19);
|
||||
Color get sc20 => getColor(color20);
|
||||
Color get sc21 => getColor(color21);
|
||||
Color get sc25 => getColor(color25);
|
||||
Color get sc26 => getColor(color26);
|
||||
Color get sc27 => getColor(color27);
|
||||
Color get sc28 => getColor(color28);
|
||||
Color get sc29 => getColor(color29);
|
||||
Color get sc30 => getColor(color30);
|
||||
Color get sc31 => getColor(color31);
|
||||
Color get sc32 => getColor(color32);
|
||||
Color get sc33 => getColor(color33);
|
||||
Color get sc34 => getColor(color34);
|
||||
Color get sc38 => getColor(color38);
|
||||
Color get sc39 => getColor(color39);
|
||||
Color get sc40 => getColor(color40);
|
||||
|
||||
Color getColor(String color) {
|
||||
color = color.replaceAll("#", "");
|
||||
|
||||
if (color.length == 6) {
|
||||
color = "0xFF$color";
|
||||
} else {
|
||||
color = "0x$color";
|
||||
}
|
||||
|
||||
return Color(int.parse(color));
|
||||
}
|
||||
|
||||
//序列化反序列化
|
||||
factory CustomThemeColor.fromJson(Map<String, dynamic> json) =>
|
||||
CustomThemeColor(
|
||||
color1: json['color1'],
|
||||
color2: json['color2'],
|
||||
color3: json['color3'],
|
||||
color4: json['color4'],
|
||||
color5: json['color5'],
|
||||
color6: json['color6'],
|
||||
color7: json['color7'],
|
||||
color8: json['color8'],
|
||||
color9: json['color9'],
|
||||
color10: json['color10'],
|
||||
color11: json['color11'],
|
||||
color12: json['color12'],
|
||||
color13: json['color13'],
|
||||
color14: json['color14'],
|
||||
color15: json['color15'],
|
||||
color16: json['color16'],
|
||||
color17: json['color17'],
|
||||
color18: json['color18'],
|
||||
color19: json['color19'],
|
||||
color20: json['color20'],
|
||||
color21: json['color21'],
|
||||
color25: json['color25'],
|
||||
color26: json['color26'],
|
||||
color27: json['color27'],
|
||||
color28: json['color28'],
|
||||
color29: json['color29'],
|
||||
color30: json['color30'],
|
||||
color31: json['color31'],
|
||||
color32: json['color32'],
|
||||
color33: json['color33'],
|
||||
color34: json['color34'],
|
||||
color38: json['color38'],
|
||||
color39: json['color39'],
|
||||
color40: json['color40']);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'color1': color1,
|
||||
'color2': color2,
|
||||
'color3': color3,
|
||||
'color4': color4,
|
||||
'color5': color5,
|
||||
'color6': color6,
|
||||
'color7': color7,
|
||||
'color8': color8,
|
||||
'color9': color9,
|
||||
'color10': color10,
|
||||
'color11': color11,
|
||||
'color12': color12,
|
||||
'color13': color13,
|
||||
'color14': color14,
|
||||
'color15': color15,
|
||||
'color16': color16,
|
||||
'color17': color17,
|
||||
'color18': color18,
|
||||
'color19': color19,
|
||||
'color20': color20,
|
||||
'color21': color21,
|
||||
'color25': color25,
|
||||
'color26': color26,
|
||||
'color27': color27,
|
||||
'color28': color28,
|
||||
'color29': color29,
|
||||
'color30': color30,
|
||||
'color31': color31,
|
||||
'color32': color32,
|
||||
'color33': color33,
|
||||
'color34': color34,
|
||||
'color38': color38,
|
||||
'color39': color39,
|
||||
'color40': color40,
|
||||
};
|
||||
}
|
||||
17
lib/model/api_response.dart
Normal file
17
lib/model/api_response.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
class ApiResponse<T> {
|
||||
int? code;
|
||||
T? data;
|
||||
String? msg;
|
||||
|
||||
ApiResponse({required this.code, this.data, this.msg});
|
||||
factory ApiResponse.fromJson(
|
||||
Map<String, dynamic> json, T Function(Object?) fromJsonT) {
|
||||
return ApiResponse<T>(
|
||||
code: json['code'] as int,
|
||||
data: json['data'] != null ? fromJsonT(json['data']) : null,
|
||||
msg: json['msg'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
22
lib/model/device.dart
Normal file
22
lib/model/device.dart
Normal file
@@ -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<DeviceShareModel> shareInfo = []; //设备分享信息
|
||||
|
||||
DeviceModel();
|
||||
static DeviceModel fromJson(Map<String, dynamic> json) =>
|
||||
_$DeviceModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$DeviceModelToJson(this);
|
||||
}
|
||||
23
lib/model/device.g.dart
Normal file
23
lib/model/device.g.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'device.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
DeviceModel _$DeviceModelFromJson(Map<String, dynamic> 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<String, dynamic> _$DeviceModelToJson(DeviceModel instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'id': instance.id,
|
||||
'status': instance.status,
|
||||
'roomName': instance.roomName,
|
||||
'shareNum': instance.shareNum,
|
||||
};
|
||||
15
lib/model/device_share.dart
Normal file
15
lib/model/device_share.dart
Normal file
@@ -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<String, dynamic> json) =>
|
||||
_$DeviceShareModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$DeviceShareModelToJson(this);
|
||||
}
|
||||
22
lib/model/device_share.g.dart
Normal file
22
lib/model/device_share.g.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'device_share.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
DeviceShareModel _$DeviceShareModelFromJson(Map<String, dynamic> 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<String, dynamic> _$DeviceShareModelToJson(DeviceShareModel instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'phone': instance.phone,
|
||||
'share_time': instance.share_time?.toIso8601String(),
|
||||
};
|
||||
19
lib/model/experience_store.dart
Normal file
19
lib/model/experience_store.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'experience_store.g.dart';
|
||||
|
||||
|
||||
//体验店
|
||||
@JsonSerializable()
|
||||
class ExperienceStoreModel {
|
||||
String? name; //设备名称
|
||||
String? phone; //店铺电话
|
||||
String? address; //店铺地址
|
||||
|
||||
|
||||
|
||||
ExperienceStoreModel();
|
||||
static ExperienceStoreModel fromJson(Map<String, dynamic> json) =>
|
||||
_$ExperienceStoreModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ExperienceStoreModelToJson(this);
|
||||
}
|
||||
22
lib/model/experience_store.g.dart
Normal file
22
lib/model/experience_store.g.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'experience_store.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ExperienceStoreModel _$ExperienceStoreModelFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
ExperienceStoreModel()
|
||||
..name = json['name'] as String?
|
||||
..phone = json['phone'] as String?
|
||||
..address = json['address'] as String?;
|
||||
|
||||
Map<String, dynamic> _$ExperienceStoreModelToJson(
|
||||
ExperienceStoreModel instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'phone': instance.phone,
|
||||
'address': instance.address,
|
||||
};
|
||||
14
lib/model/issue.dart
Normal file
14
lib/model/issue.dart
Normal file
@@ -0,0 +1,14 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'issue.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class IssueModel {
|
||||
String? title;
|
||||
String? title_content;
|
||||
|
||||
IssueModel();
|
||||
static IssueModel fromJson(Map<String, dynamic> json) =>
|
||||
_$IssueModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$IssueModelToJson(this);
|
||||
}
|
||||
17
lib/model/issue.g.dart
Normal file
17
lib/model/issue.g.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'issue.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
IssueModel _$IssueModelFromJson(Map<String, dynamic> json) => IssueModel()
|
||||
..title = json['title'] as String?
|
||||
..title_content = json['title_content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$IssueModelToJson(IssueModel instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'title_content': instance.title_content,
|
||||
};
|
||||
19
lib/model/message.dart
Normal file
19
lib/model/message.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'message.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class MessageModel {
|
||||
String? title;//消息名称
|
||||
String? did;//消息设备id
|
||||
String? userId;//消息用户id
|
||||
String? userName;//消息用户名称
|
||||
DateTime? createTime;//消息创建时间
|
||||
int? type;//消息类型
|
||||
|
||||
|
||||
MessageModel();
|
||||
static MessageModel fromJson(Map<String, dynamic> json) =>
|
||||
_$MessageModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$MessageModelToJson(this);
|
||||
}
|
||||
27
lib/model/message.g.dart
Normal file
27
lib/model/message.g.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'message.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MessageModel _$MessageModelFromJson(Map<String, dynamic> json) => MessageModel()
|
||||
..title = json['title'] as String?
|
||||
..did = json['did'] as String?
|
||||
..userId = json['userId'] as String?
|
||||
..userName = json['userName'] as String?
|
||||
..createTime = json['createTime'] == null
|
||||
? null
|
||||
: DateTime.parse(json['createTime'] as String)
|
||||
..type = (json['type'] as num?)?.toInt();
|
||||
|
||||
Map<String, dynamic> _$MessageModelToJson(MessageModel instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'did': instance.did,
|
||||
'userId': instance.userId,
|
||||
'userName': instance.userName,
|
||||
'createTime': instance.createTime?.toIso8601String(),
|
||||
'type': instance.type,
|
||||
};
|
||||
32
lib/model/order.dart
Normal file
32
lib/model/order.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'order.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class OrderModel {
|
||||
String? goods_name; //商品名称
|
||||
String? goods_id; //商品id
|
||||
String? id; //订单id
|
||||
double? price; //支付金额
|
||||
String? tel; //电话号码
|
||||
String? addition_address; //详细地址
|
||||
// DateTime? create_time; //创建时间
|
||||
int? create_time; //创建时间
|
||||
String? desc; //审核意见
|
||||
String? create_user_id; //下单用户id
|
||||
String? create_user_name; //下单用户名称
|
||||
int? order_status; //订单状态
|
||||
String? delivery_status; //物流状态
|
||||
int? order_num; //商品数量
|
||||
String? province; //省份
|
||||
String? city; //城市
|
||||
String? county; //区域
|
||||
String? street; //街道
|
||||
double? goods_price; //商品单价
|
||||
String? pay_status; //支付状态
|
||||
|
||||
OrderModel();
|
||||
static OrderModel fromJson(Map<String, dynamic> json) =>
|
||||
_$OrderModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$OrderModelToJson(this);
|
||||
}
|
||||
51
lib/model/order.g.dart
Normal file
51
lib/model/order.g.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'order.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
OrderModel _$OrderModelFromJson(Map<String, dynamic> json) => OrderModel()
|
||||
..goods_name = json['goods_name'] as String?
|
||||
..goods_id = json['goods_id'] as String?
|
||||
..id = json['id'] as String?
|
||||
..price = (json['price'] as num?)?.toDouble()
|
||||
..tel = json['tel'] as String?
|
||||
..addition_address = json['addition_address'] as String?
|
||||
..create_time = (json['create_time'] as num?)?.toInt()
|
||||
..desc = json['desc'] as String?
|
||||
..create_user_id = json['create_user_id'] as String?
|
||||
..create_user_name = json['create_user_name'] as String?
|
||||
..order_status = (json['order_status'] as num?)?.toInt()
|
||||
..delivery_status = json['delivery_status'] as String?
|
||||
..order_num = (json['order_num'] as num?)?.toInt()
|
||||
..province = json['province'] as String?
|
||||
..city = json['city'] as String?
|
||||
..county = json['county'] as String?
|
||||
..street = json['street'] as String?
|
||||
..goods_price = (json['goods_price'] as num?)?.toDouble()
|
||||
..pay_status = json['pay_status'] as String?;
|
||||
|
||||
Map<String, dynamic> _$OrderModelToJson(OrderModel instance) =>
|
||||
<String, dynamic>{
|
||||
'goods_name': instance.goods_name,
|
||||
'goods_id': instance.goods_id,
|
||||
'id': instance.id,
|
||||
'price': instance.price,
|
||||
'tel': instance.tel,
|
||||
'addition_address': instance.addition_address,
|
||||
'create_time': instance.create_time,
|
||||
'desc': instance.desc,
|
||||
'create_user_id': instance.create_user_id,
|
||||
'create_user_name': instance.create_user_name,
|
||||
'order_status': instance.order_status,
|
||||
'delivery_status': instance.delivery_status,
|
||||
'order_num': instance.order_num,
|
||||
'province': instance.province,
|
||||
'city': instance.city,
|
||||
'county': instance.county,
|
||||
'street': instance.street,
|
||||
'goods_price': instance.goods_price,
|
||||
'pay_status': instance.pay_status,
|
||||
};
|
||||
18
lib/model/repair_process.dart
Normal file
18
lib/model/repair_process.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'repair_process.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class RepairProcessModel {
|
||||
String? status; //审核状态
|
||||
DateTime? create_time; //审核时间
|
||||
String? desc; //审核意见
|
||||
int? record_id; //归属记录
|
||||
|
||||
int? deal_user; //处理人
|
||||
|
||||
RepairProcessModel();
|
||||
static RepairProcessModel fromJson(Map<String, dynamic> json) =>
|
||||
_$RepairProcessModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$RepairProcessModelToJson(this);
|
||||
}
|
||||
26
lib/model/repair_process.g.dart
Normal file
26
lib/model/repair_process.g.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'repair_process.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
RepairProcessModel _$RepairProcessModelFromJson(Map<String, dynamic> json) =>
|
||||
RepairProcessModel()
|
||||
..status = json['status'] as String?
|
||||
..create_time = json['create_time'] == null
|
||||
? null
|
||||
: DateTime.parse(json['create_time'] as String)
|
||||
..desc = json['desc'] as String?
|
||||
..record_id = (json['record_id'] as num?)?.toInt()
|
||||
..deal_user = (json['deal_user'] as num?)?.toInt();
|
||||
|
||||
Map<String, dynamic> _$RepairProcessModelToJson(RepairProcessModel instance) =>
|
||||
<String, dynamic>{
|
||||
'status': instance.status,
|
||||
'create_time': instance.create_time?.toIso8601String(),
|
||||
'desc': instance.desc,
|
||||
'record_id': instance.record_id,
|
||||
'deal_user': instance.deal_user,
|
||||
};
|
||||
20
lib/model/user_data.dart
Normal file
20
lib/model/user_data.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'user_data.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class UserModel {
|
||||
String? uid;
|
||||
String? userName;
|
||||
String? nickName;
|
||||
String? tel;
|
||||
String? exp1;
|
||||
String? head;
|
||||
String? tmpHead;
|
||||
String? tmpNickName;
|
||||
|
||||
UserModel();
|
||||
static UserModel fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$UserModelToJson(this);
|
||||
}
|
||||
28
lib/model/user_data.g.dart
Normal file
28
lib/model/user_data.g.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'user_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
UserModel _$UserModelFromJson(Map<String, dynamic> json) => UserModel()
|
||||
..uid = json['uid'] as String?
|
||||
..userName = json['userName'] as String?
|
||||
..nickName = json['nickName'] as String?
|
||||
..tel = json['tel'] as String?
|
||||
..exp1 = json['exp1'] as String?
|
||||
..head = json['head'] as String?
|
||||
..tmpHead = json['tmpHead'] as String?
|
||||
..tmpNickName = json['tmpNickName'] as String?;
|
||||
|
||||
Map<String, dynamic> _$UserModelToJson(UserModel instance) => <String, dynamic>{
|
||||
'uid': instance.uid,
|
||||
'userName': instance.userName,
|
||||
'nickName': instance.nickName,
|
||||
'tel': instance.tel,
|
||||
'exp1': instance.exp1,
|
||||
'head': instance.head,
|
||||
'tmpHead': instance.tmpHead,
|
||||
'tmpNickName': instance.tmpNickName,
|
||||
};
|
||||
366
lib/pages/device_bind/device_type.dart
Normal file
366
lib/pages/device_bind/device_type.dart
Normal file
@@ -0,0 +1,366 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/component/tool/CustomCard.dart';
|
||||
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class DeviceTypePage extends StatefulWidget {
|
||||
const DeviceTypePage({super.key});
|
||||
|
||||
@override
|
||||
State<DeviceTypePage> createState() => _EPageState();
|
||||
}
|
||||
|
||||
class _EPageState extends State<DeviceTypePage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
BlueteethBindController blueteethBindController = Get.find();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// 延迟到 build 完成后执行弹窗逻辑
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (blueteethBindController.model.read == 1) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.sizeOf(context).height * 0.656,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 26.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFBF5D5),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConstants()
|
||||
.normal_container_radius), // 圆角半径
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
25.rpx, 25.rpx, 25.rpx, 25.rpx),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.volume_mute,
|
||||
color:
|
||||
FlutterFlowTheme.of(context)
|
||||
.primaryText,
|
||||
size: 30.rpx,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'绑定引导.说明标题'.tr,
|
||||
style: FlutterFlowTheme.of(
|
||||
context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
color:
|
||||
Colors.orange),
|
||||
),
|
||||
Text(
|
||||
'绑定引导.说明正文'.tr,
|
||||
style: FlutterFlowTheme.of(
|
||||
context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(
|
||||
height: AppConstants()
|
||||
.text_padding_up_dowm_p)),
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 20.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.sizeOf(context).height *
|
||||
0.26,
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 421.rpx,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius:
|
||||
BorderRadius.circular(20.rpx),
|
||||
child: Image.network(
|
||||
'https://picsum.photos/seed/861/600',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(height: 25.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 210.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_back,
|
||||
color: FlutterFlowTheme.of(context)
|
||||
.primaryText,
|
||||
size: 24.rpx,
|
||||
),
|
||||
Text(
|
||||
'绑定引导.不再提示'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
),
|
||||
CustomCard(
|
||||
borderRadius: 50.rpx,
|
||||
onTap: () async {
|
||||
await Future.delayed(
|
||||
Duration(seconds: 1));
|
||||
Get.back(); // 关闭当前弹窗或页面
|
||||
},
|
||||
colors: [
|
||||
Colors.yellow,
|
||||
Colors.green
|
||||
], // 单色背景也用渐变写法
|
||||
title: '',
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width *
|
||||
0.66,
|
||||
height:
|
||||
MediaQuery.sizeOf(context).height *
|
||||
0.055,
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 500.rpx,
|
||||
minHeight: 90.rpx,
|
||||
),
|
||||
alignment: Alignment.center, // 居中对齐
|
||||
child: Text(
|
||||
'绑定引导.跳过'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
].divide(SizedBox(height: 42.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
int read = blueteethBindController.model.read;
|
||||
if (blueteethBindController.model.read == 1) {
|
||||
//需要弹窗显示教程
|
||||
}
|
||||
return LayoutBuilder(
|
||||
builder: (context, bodySize) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
|
||||
fit: BoxFit.fill, // 填满整个 Container
|
||||
),
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.transparent, // 加上这一行
|
||||
appBar: AppBar(
|
||||
backgroundColor: stringToColor("#242835"),
|
||||
// backgroundColor: Colors.transparent,
|
||||
automaticallyImplyLeading: false,
|
||||
// iconTheme: IconThemeData(color: Colors.white),
|
||||
titleSpacing: 0,
|
||||
// leading: returnIconButtom,
|
||||
title: Container(
|
||||
// color: Colors.grey,
|
||||
width: double.infinity,
|
||||
height: 180.rpx,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
/// 居中标题
|
||||
Text(
|
||||
'设备列表',
|
||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: Colors.white,
|
||||
letterSpacing: 0,
|
||||
fontSize: 30.rpx,
|
||||
),
|
||||
),
|
||||
|
||||
/// 左边返回按钮
|
||||
Positioned(
|
||||
left: 0,
|
||||
child: returnIconButtom,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
actions: [],
|
||||
centerTitle: false,
|
||||
),
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
_buildDeviceCard(
|
||||
context,
|
||||
title: '设备类型.体征监测设备'.tr,
|
||||
imageUrl: 'assets/img/device.png',
|
||||
),
|
||||
_buildDeviceCard(
|
||||
context,
|
||||
title: '设备类型.智能床/床垫'.tr,
|
||||
imageUrl: 'assets/img/bed.png',
|
||||
),
|
||||
_buildDeviceCard(
|
||||
context,
|
||||
title: '设备类型.摄像头'.tr,
|
||||
imageUrl: 'assets/img/camera.png',
|
||||
),
|
||||
]
|
||||
.divide(SizedBox(height: 26.rpx))
|
||||
.addToStart(SizedBox(height: 26.rpx))
|
||||
.addToEnd(SizedBox(height: 26.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceCard(BuildContext context,
|
||||
{required String title, required String imageUrl}) {
|
||||
return CustomCard(
|
||||
borderRadius: 20.rpx, // 圆角大小
|
||||
onTap: () {
|
||||
print('点击了 $title');
|
||||
},
|
||||
// colors: [Colors.white.withOpacity(0.06)], // 背景色
|
||||
colors: [stringToColor("45D989"), stringToColor("00C1AA")], // 背景色
|
||||
title: title,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.sizeOf(context).height * 0.135,
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 220.rpx,
|
||||
),
|
||||
padding: EdgeInsetsDirectional.fromSTEB(77.rpx, 0, 21.rpx, 0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||
fontFamily: 'Inter',
|
||||
color: const Color(0xFFC2CED7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.rpx),
|
||||
child: Image.asset(
|
||||
imageUrl,
|
||||
width: 212.rpx,
|
||||
height: 168.rpx,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
276
lib/pages/login/login.dart
Normal file
276
lib/pages/login/login.dart
Normal file
@@ -0,0 +1,276 @@
|
||||
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/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
|
||||
@override
|
||||
State<LoginPage> createState() => _EPageState();
|
||||
}
|
||||
|
||||
class _EPageState extends State<LoginPage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, boxConstraints) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(-1, 0),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
35.rpx, 66.rpx, 0, 0),
|
||||
child: Icon(
|
||||
Icons.arrow_back,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
size: 24.rpx,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional(-1, 0),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 141.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(0, 0),
|
||||
child: Text(
|
||||
'欢迎使用太和e护',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 48.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional(-1, 0),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 15.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(0, 0),
|
||||
child: Text(
|
||||
'科技睡眠 洞悉万千',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional(-1, 0),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 95.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(0, 0),
|
||||
child: Text(
|
||||
'139****0733',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 48.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 35.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width * 0.8,
|
||||
height: MediaQuery.sizeOf(context).height * 0.055,
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 500.rpx,
|
||||
minHeight: 90.rpx,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF01515),
|
||||
borderRadius: BorderRadius.circular(50.rpx),
|
||||
),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(0, 0),
|
||||
child: Text(
|
||||
'本机号码一键登录/注册',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional(-1, 0),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 32.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Align(
|
||||
alignment: AlignmentDirectional(0, 0),
|
||||
child: Text(
|
||||
'其他手机号码',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
110.rpx, 136.rpx, 110.rpx, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_back,
|
||||
color:
|
||||
FlutterFlowTheme.of(context).primaryText,
|
||||
size: 24.rpx,
|
||||
),
|
||||
Expanded(
|
||||
// 👈 让文本自动换行
|
||||
child: Text(
|
||||
'登录时将自动注册,且代表您同意《用户协议》和 《隐私政策》以及《用户使用条款》',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
letterSpacing: 0.0,
|
||||
fontSize: 24.rpx, // 可选:字体稍小点更适配
|
||||
),
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 26.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.sizeOf(context).height * 0.136,
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 220.rpx,
|
||||
),
|
||||
decoration: BoxDecoration(),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 0, 0, 36.rpx),
|
||||
child: Text(
|
||||
'其他登录方式',
|
||||
style:
|
||||
FlutterFlowTheme.of(context).bodyMedium.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 91.rpx,
|
||||
height: 91.rpx,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Image.network(
|
||||
'https://picsum.photos/seed/301/600',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 91.rpx,
|
||||
height: 91.rpx,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Image.network(
|
||||
'https://picsum.photos/seed/301/600',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 35.rpx)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
85
lib/pages/main_bottom/e_page.dart
Normal file
85
lib/pages/main_bottom/e_page.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class EPage extends StatefulWidget {
|
||||
const EPage({super.key});
|
||||
|
||||
@override
|
||||
State<EPage> createState() => _EPageState();
|
||||
}
|
||||
|
||||
class _EPageState extends State<EPage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, boxConstraints) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
// appBar: AppBar(
|
||||
// backgroundColor: AppColors.bg_color,
|
||||
// automaticallyImplyLeading: false,
|
||||
// title: Container(
|
||||
// width: double.infinity,
|
||||
// height: 70.rpx,
|
||||
// child: Obx(
|
||||
// () => InkWell(
|
||||
// onTap: () {
|
||||
// Get.toNamed("/editUserInfoPage");
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 56.rpx,
|
||||
// height: 56.rpx,
|
||||
// clipBehavior: Clip.antiAlias,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// width: 20.rpx,
|
||||
// height: 0,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// shape: BoxShape.rectangle,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// userInfoController.model.user!.nickName ?? '匿名',
|
||||
// style: FlutterFlowTheme.of(context)
|
||||
// .bodyMedium
|
||||
// .override(
|
||||
// fontFamily: 'Readex Pro',
|
||||
// color: Colors.white,
|
||||
// letterSpacing: 0,
|
||||
// fontSize: 30.rpx),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// actions: [],
|
||||
// centerTitle: false,
|
||||
// ),
|
||||
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Text("小e"),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
396
lib/pages/main_bottom/home_page.dart
Normal file
396
lib/pages/main_bottom/home_page.dart
Normal file
@@ -0,0 +1,396 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/component/tool/CustomCard.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({super.key});
|
||||
|
||||
@override
|
||||
State<HomePage> createState() => _HomePageState();
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
ThemeController themeController = Get.find();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, bodySize) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
// appBar: AppBar(
|
||||
// backgroundColor: AppColors.bg_color,
|
||||
// automaticallyImplyLeading: false,
|
||||
// title: Container(
|
||||
// width: double.infinity,
|
||||
// height: 70.rpx,
|
||||
// child: Obx(
|
||||
// () => InkWell(
|
||||
// onTap: () {
|
||||
// Get.toNamed("/editUserInfoPage");
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 56.rpx,
|
||||
// height: 56.rpx,
|
||||
// clipBehavior: Clip.antiAlias,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// width: 20.rpx,
|
||||
// height: 0,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// shape: BoxShape.rectangle,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// userInfoController.model.user!.nickName ?? '匿名',
|
||||
// style: FlutterFlowTheme.of(context)
|
||||
// .bodyMedium
|
||||
// .override(
|
||||
// fontFamily: 'Readex Pro',
|
||||
// color: Colors.white,
|
||||
// letterSpacing: 0,
|
||||
// fontSize: 30.rpx),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// actions: [],
|
||||
// centerTitle: false,
|
||||
// ),
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
// child: Text("首页"),
|
||||
child: Container(
|
||||
height: bodySize.maxHeight,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/img/bgImage.png'), // 本地图片
|
||||
fit: BoxFit.fill, // 填满整个 Container
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
AppConstants().main_left_right_padding,
|
||||
47.rpx,
|
||||
AppConstants().main_left_right_padding,
|
||||
0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
AppConstants().content_left_right_padding,
|
||||
0,
|
||||
AppConstants().content_left_right_padding,
|
||||
0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
CustomCard(
|
||||
borderRadius: 20.rpx,
|
||||
onTap: () async {
|
||||
Get.toNamed("/loginPage");
|
||||
},
|
||||
title: '首页.登录'
|
||||
.tr, // 虽然 title 传入了,但当前组件里没用它(可忽略或用于调试)
|
||||
colors: [
|
||||
stringToColor("#45D989"),
|
||||
stringToColor("#00C1AA"),
|
||||
],
|
||||
child: Container(
|
||||
width: 100.rpx,
|
||||
height: 60.rpx,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
16.rpx, 0, 16.rpx, 0),
|
||||
child: Text(
|
||||
'首页.登录'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.titleSmall
|
||||
.override(
|
||||
fontFamily: 'Inter Tight',
|
||||
color: Colors.white,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Icon(
|
||||
Icons.add_circle_outline_outlined,
|
||||
color: FlutterFlowTheme.of(context).primaryText,
|
||||
size: 38.rpx,
|
||||
),
|
||||
// Lottie.asset(
|
||||
// 'assets/img/loading.json',
|
||||
// width: 200,
|
||||
// height: 200,
|
||||
// fit: BoxFit.contain,
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
19.rpx, 13.rpx, 0, 13.rpx),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'首页.已关联体征监测设备'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize:
|
||||
AppConstants().title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' 0',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize:
|
||||
AppConstants().title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height * 0.277,
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 690.rpx,
|
||||
minHeight: 450.rpx,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: stringToColor("#242835"),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConstants().normal_container_radius), // 圆角半径
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.sizeOf(context).width * 0.66,
|
||||
height: MediaQuery.sizeOf(context).height * 0.055,
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 500.rpx,
|
||||
minHeight: 90.rpx,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Colors.red, Colors.orange], // 渐变颜色数组
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConstants()
|
||||
.button_container_radius), // 圆角半径
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_back,
|
||||
color: FlutterFlowTheme.of(context)
|
||||
.primaryText,
|
||||
size: 28.rpx,
|
||||
),
|
||||
Text(
|
||||
'首页.扫一扫绑定'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(
|
||||
width: 17.rpx,
|
||||
)),
|
||||
),
|
||||
),
|
||||
CustomCard(
|
||||
borderRadius: AppConstants()
|
||||
.button_container_radius, // 圆角半径
|
||||
onTap: () {
|
||||
print('Button pressed ...');
|
||||
Get.toNamed("/deviceType");
|
||||
},
|
||||
colors: [
|
||||
stringToColor("45D989"),
|
||||
stringToColor("00C1AA")
|
||||
], // 渐变色是同一个色,也可以根据需要调整
|
||||
title: '首页.蓝牙绑定'.tr, // 可选,虽然这个 title 没用,但可以作为调试用
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width * 0.66,
|
||||
height:
|
||||
MediaQuery.sizeOf(context).height * 0.055,
|
||||
constraints: BoxConstraints(
|
||||
minWidth: 500.rpx,
|
||||
minHeight: 90.rpx,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_back,
|
||||
color: FlutterFlowTheme.of(context)
|
||||
.primaryText,
|
||||
size: 28.rpx,
|
||||
),
|
||||
Text(
|
||||
'首页.蓝牙绑定'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(
|
||||
width: 17.rpx,
|
||||
)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 26.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFBF5D5),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConstants().normal_container_radius), // 圆角半径
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
25.rpx, 25.rpx, 25.rpx, 25.rpx),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.volume_mute,
|
||||
color:
|
||||
FlutterFlowTheme.of(context).primaryText,
|
||||
size: 30.rpx,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'首页.提示标题'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.orange),
|
||||
),
|
||||
Text(
|
||||
'首页.提示内容1'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'首页.提示内容2'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'首页.提示内容3'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(
|
||||
height: AppConstants()
|
||||
.text_padding_up_dowm_p)),
|
||||
),
|
||||
)
|
||||
].divide(SizedBox(width: 20.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
192
lib/pages/main_bottom/main_page_bottom_change.dart
Normal file
192
lib/pages/main_bottom/main_page_bottom_change.dart
Normal file
@@ -0,0 +1,192 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/common/util/MyUtils.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
|
||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||
import 'package:vbvs_app/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';
|
||||
import 'package:vbvs_app/pages/main_bottom/sleep_report_page.dart';
|
||||
|
||||
class MainPageBottomChange extends GetView<MainPageController> {
|
||||
GlobalController globalController = Get.find();
|
||||
ThemeController themeController = Get.find();
|
||||
getBottomNavigationBarItem(String svgPath, String actSvgPath, String label,
|
||||
{double size = 0, bool isEmpty = false}) {
|
||||
if (size == 0) {
|
||||
size = 36.rpx;
|
||||
}
|
||||
return BottomNavigationBarItem(
|
||||
icon: Padding(
|
||||
padding: EdgeInsets.only(bottom: 6.rpx),
|
||||
child: isEmpty
|
||||
? Container()
|
||||
: SvgPicture.asset(
|
||||
actSvgPath,
|
||||
width: size,
|
||||
height: size,
|
||||
),
|
||||
),
|
||||
// activeIcon: Padding(
|
||||
// padding: EdgeInsets.only(bottom: 6.rpx),
|
||||
// child: isEmpty
|
||||
// ? Container()
|
||||
// : SvgPicture.asset(
|
||||
// svgPath,
|
||||
// color: stringToColor("#D3B684"),
|
||||
// width: size,
|
||||
// height: size,
|
||||
// ),
|
||||
// ),
|
||||
activeIcon: Padding(
|
||||
padding: EdgeInsets.only(bottom: 6.rpx),
|
||||
child: isEmpty
|
||||
? Container()
|
||||
: SvgPicture.asset(
|
||||
svgPath,
|
||||
width: size,
|
||||
height: size,
|
||||
),
|
||||
),
|
||||
label: label);
|
||||
}
|
||||
|
||||
List arr = [
|
||||
HomePage(),
|
||||
SleepReportPage(),
|
||||
EPage(),
|
||||
MessagePage(),
|
||||
MinePage(),
|
||||
];
|
||||
|
||||
DateTime? _lastBackPressedTime; // 记录上一次返回的时间
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (disposition, result) async {
|
||||
if (Platform.isAndroid) {
|
||||
var flag = await _handleBackPressed(context); // 自定义返回逻辑
|
||||
if (flag) {
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Obx(
|
||||
() {
|
||||
if (globalController.model.hideBottomNavigationBar == true) {
|
||||
return Scaffold(
|
||||
body: arr[controller.model.currentIndex],
|
||||
floatingActionButtonAnimator:
|
||||
FloatingActionButtonAnimator.noAnimation,
|
||||
floatingActionButton: Container(),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
body: arr[controller.model.currentIndex],
|
||||
floatingActionButtonAnimator:
|
||||
FloatingActionButtonAnimator.noAnimation,
|
||||
// floatingActionButton: Stack(
|
||||
// alignment: Alignment.center,
|
||||
// children: [
|
||||
// Positioned(
|
||||
// bottom: 10.rpx,
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// print("index 3");
|
||||
// if (globalController.model.deviceList.length == 0) {
|
||||
// showToast("请先绑定设备");
|
||||
// return;
|
||||
// }
|
||||
// if (globalController.model.deviceMain == null ||
|
||||
// globalController.model.deviceMain["mac"] == null) {
|
||||
// globalController.model.deviceMain =
|
||||
// globalController.model.deviceList[0];
|
||||
// globalController.updateAll();
|
||||
// }
|
||||
|
||||
// controller.model.currentIndex = 2;
|
||||
// controller.updateAll();
|
||||
// },
|
||||
// child: Image.asset(
|
||||
// gaplessPlayback: true,
|
||||
// excludeFromSemantics: true,
|
||||
// controller.model.currentIndex == 2
|
||||
// ? "assets/images/icon_sleep_light.png"
|
||||
// : "assets/images/icon_sleep_dark.png",
|
||||
// width: 120.rpx,
|
||||
// height: 120.rpx,
|
||||
// ),
|
||||
// )),
|
||||
// ],
|
||||
// ),
|
||||
floatingActionButtonLocation:
|
||||
FloatingActionButtonLocation.centerDocked,
|
||||
bottomNavigationBar: Theme(
|
||||
data: ThemeData(
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
highlightColor: Colors.transparent),
|
||||
child: BottomNavigationBar(
|
||||
unselectedItemColor: Colors.white,
|
||||
selectedItemColor: stringToColor("#D3B684"),
|
||||
backgroundColor: themeController.currentColor.sc5,
|
||||
selectedFontSize: 26.rpx,
|
||||
unselectedFontSize: 26.rpx,
|
||||
type: BottomNavigationBarType.fixed,
|
||||
currentIndex: controller.model.currentIndex,
|
||||
onTap: (index) {
|
||||
// if(controller.model.currentIndex == 2) {
|
||||
// arr[2].closeBefore();
|
||||
// }
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (controller.model.currentIndex != 1) {
|
||||
globalController.model.hideBottomNavigationBar = false;
|
||||
globalController.updateAll();
|
||||
}
|
||||
});
|
||||
controller.model.currentIndex = index;
|
||||
controller.updateAll();
|
||||
},
|
||||
items: [
|
||||
getBottomNavigationBarItem("assets/img/menu/home.svg",
|
||||
"assets/img/menu/n_home.svg", "菜单.首页".tr),
|
||||
getBottomNavigationBarItem("assets/img/menu/report.svg",
|
||||
"assets/img/menu/n_report.svg", "菜单.报告".tr),
|
||||
getBottomNavigationBarItem("assets/img/menu/e.svg",
|
||||
"assets/img/menu/n_e.svg", "菜单.小e".tr),
|
||||
getBottomNavigationBarItem("assets/img/menu/message.svg",
|
||||
"assets/img/menu/n_message.svg", "菜单.消息".tr),
|
||||
getBottomNavigationBarItem("assets/img/menu/mine.svg",
|
||||
"assets/img/menu/n_mine.svg", "菜单.我的".tr),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> _handleBackPressed(BuildContext context) async {
|
||||
final currentTime = DateTime.now();
|
||||
|
||||
// 如果上次点击返回键时间为空,或者间隔超过 1 秒
|
||||
if (_lastBackPressedTime == null ||
|
||||
currentTime.difference(_lastBackPressedTime!) > Duration(seconds: 2)) {
|
||||
_lastBackPressedTime = currentTime;
|
||||
showToast("再按一次退出程序", color: color_warning, closeTime: 2);
|
||||
return false; // 阻止退出程序
|
||||
} else {
|
||||
return true; // 允许退出程序
|
||||
}
|
||||
}
|
||||
}
|
||||
85
lib/pages/main_bottom/message_page.dart
Normal file
85
lib/pages/main_bottom/message_page.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class MessagePage extends StatefulWidget {
|
||||
const MessagePage({super.key});
|
||||
|
||||
@override
|
||||
State<MessagePage> createState() => _MessagePageState();
|
||||
}
|
||||
|
||||
class _MessagePageState extends State<MessagePage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, boxConstraints) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
// appBar: AppBar(
|
||||
// backgroundColor: AppColors.bg_color,
|
||||
// automaticallyImplyLeading: false,
|
||||
// title: Container(
|
||||
// width: double.infinity,
|
||||
// height: 70.rpx,
|
||||
// child: Obx(
|
||||
// () => InkWell(
|
||||
// onTap: () {
|
||||
// Get.toNamed("/editUserInfoPage");
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 56.rpx,
|
||||
// height: 56.rpx,
|
||||
// clipBehavior: Clip.antiAlias,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// width: 20.rpx,
|
||||
// height: 0,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// shape: BoxShape.rectangle,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// userInfoController.model.user!.nickName ?? '匿名',
|
||||
// style: FlutterFlowTheme.of(context)
|
||||
// .bodyMedium
|
||||
// .override(
|
||||
// fontFamily: 'Readex Pro',
|
||||
// color: Colors.white,
|
||||
// letterSpacing: 0,
|
||||
// fontSize: 30.rpx),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// actions: [],
|
||||
// centerTitle: false,
|
||||
// ),
|
||||
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Text("消息"),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
374
lib/pages/main_bottom/mine_page.dart
Normal file
374
lib/pages/main_bottom/mine_page.dart
Normal file
@@ -0,0 +1,374 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class MinePage extends StatefulWidget {
|
||||
const MinePage({super.key});
|
||||
|
||||
@override
|
||||
State<MinePage> createState() => _MinePageState();
|
||||
}
|
||||
|
||||
class _MinePageState extends State<MinePage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, bodySize) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Container(
|
||||
height: bodySize.maxHeight,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/img/bgImage.png'), // 本地图片
|
||||
fit: BoxFit.fill, // 填满整个 Container
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF242835),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(
|
||||
AppConstants().normal_container_radius),
|
||||
bottomRight: Radius.circular(
|
||||
AppConstants().normal_container_radius),
|
||||
topLeft: Radius.circular(0.rpx),
|
||||
topRight: Radius.circular(0.rpx),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(64.rpx, 0, 37.rpx, 0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(0, 65.rpx, 0, 0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/earphone.svg',
|
||||
width: 29.rpx,
|
||||
height: 29.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/setting.svg',
|
||||
width: 29.rpx,
|
||||
height: 29.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
].divide(SizedBox(width: 60.rpx)),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 50.rpx, 0, 66.rpx),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
width: 120.rpx,
|
||||
height: 120.rpx,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Image.network(
|
||||
'https://picsum.photos/seed/270/600',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
'Hello World',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFEFF3F8),
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Hello World',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFEAEFF3),
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(height: 20.rpx)),
|
||||
),
|
||||
].divide(SizedBox(width: 35.rpx)),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
'我的.个人信息'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E4E6),
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
].divide(SizedBox(width: 16.rpx)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
30.rpx, 25.rpx, 30.rpx, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF242835),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConstants().normal_container_radius),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
40.rpx, 0, 40.rpx, 0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/my_device.svg',
|
||||
width: 25.rpx,
|
||||
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
Text(
|
||||
'我的.我的设备'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E2E4),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/device_repair.svg',
|
||||
width: 25.rpx,
|
||||
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
Text(
|
||||
'我的.设备报修'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E2E4),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/op_ex.svg',
|
||||
width: 25.rpx,
|
||||
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
Text(
|
||||
'我的.操作说明'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E2E4),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/like.svg',
|
||||
width: 25.rpx,
|
||||
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
Text(
|
||||
'关注我们'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E2E4),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/version.svg',
|
||||
width: 25.rpx,
|
||||
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
Text(
|
||||
'我的.当前版本'.tr,
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFE0E2E4),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
'3.61.0',
|
||||
style: FlutterFlowTheme.of(context)
|
||||
.bodyMedium
|
||||
.override(
|
||||
fontFamily: 'Inter',
|
||||
color: Color(0xFFD9E3EB),
|
||||
fontSize: 26.rpx,
|
||||
letterSpacing: 0.0,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/arrow_right.svg',
|
||||
width: 8.rpx,
|
||||
height: 15.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
|
||||
),
|
||||
].divide(SizedBox(width: 28.rpx)),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
.divide(SizedBox(height: 60.rpx))
|
||||
.addToStart(SizedBox(height: 60.rpx))
|
||||
.addToEnd(SizedBox(height: 60.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
85
lib/pages/main_bottom/sleep_report_page.dart
Normal file
85
lib/pages/main_bottom/sleep_report_page.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
|
||||
import 'package:vbvs_app/controller/user_info_controller.dart';
|
||||
|
||||
class SleepReportPage extends StatefulWidget {
|
||||
const SleepReportPage({super.key});
|
||||
|
||||
@override
|
||||
State<SleepReportPage> createState() => _SleepReportPageState();
|
||||
}
|
||||
|
||||
class _SleepReportPageState extends State<SleepReportPage> {
|
||||
GlobalController globalController = Get.find();
|
||||
UserInfoController userInfoController = Get.find();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, boxConstraints) => GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
child: Scaffold(
|
||||
// appBar: AppBar(
|
||||
// backgroundColor: AppColors.bg_color,
|
||||
// automaticallyImplyLeading: false,
|
||||
// title: Container(
|
||||
// width: double.infinity,
|
||||
// height: 70.rpx,
|
||||
// child: Obx(
|
||||
// () => InkWell(
|
||||
// onTap: () {
|
||||
// Get.toNamed("/editUserInfoPage");
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 56.rpx,
|
||||
// height: 56.rpx,
|
||||
// clipBehavior: Clip.antiAlias,
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// width: 20.rpx,
|
||||
// height: 0,
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// shape: BoxShape.rectangle,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// userInfoController.model.user!.nickName ?? '匿名',
|
||||
// style: FlutterFlowTheme.of(context)
|
||||
// .bodyMedium
|
||||
// .override(
|
||||
// fontFamily: 'Readex Pro',
|
||||
// color: Colors.white,
|
||||
// letterSpacing: 0,
|
||||
// fontSize: 30.rpx),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// actions: [],
|
||||
// centerTitle: false,
|
||||
// ),
|
||||
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: Text("睡眠报告"),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
21
lib/repository/help_repository.dart
Normal file
21
lib/repository/help_repository.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'package:ef/ef.dart';
|
||||
|
||||
//问题与帮助
|
||||
class HelpRepository {
|
||||
//查询记录
|
||||
Future findHelpInfos({int limit = 10, int offset = 0}) async {
|
||||
try {
|
||||
var response = await ef.client
|
||||
.from('app_help_list')
|
||||
.select()
|
||||
// .eq('deleted', 0)
|
||||
.eq('status', 1)
|
||||
.order("priority", ascending: true)
|
||||
.order("created_at", ascending: false);
|
||||
return response as List<dynamic>;
|
||||
} catch (e) {
|
||||
print('Error fetching repairs: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
47
lib/routers/routers.dart
Normal file
47
lib/routers/routers.dart
Normal file
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:vbvs_app/pages/device_bind/device_type.dart';
|
||||
import 'package:vbvs_app/pages/login/login.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/main_page_bottom_change.dart';
|
||||
import 'package:vbvs_app/pages/main_bottom/message_page.dart';
|
||||
import 'package:vbvs_app/pages/main_bottom/mine_page.dart';
|
||||
import 'package:vbvs_app/pages/main_bottom/sleep_report_page.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
var routes = {
|
||||
"/homePage": (contxt) => HomePage(),
|
||||
"/sleepReportPage": (contxt) => SleepReportPage(),
|
||||
"/ePage": (contxt) => EPage(),
|
||||
"/messagePage": (contxt) => MessagePage(),
|
||||
"/minePage": (contxt) => MinePage(),
|
||||
"/mianPageBottomChange": (contxt) => MainPageBottomChange(),
|
||||
"/loginPage": (contxt) => LoginPage(),
|
||||
"/deviceType": (contxt) => DeviceTypePage(),
|
||||
};
|
||||
|
||||
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
|
||||
var onGenerateRoute = (RouteSettings settings) {
|
||||
final String? name = settings.name; // /news 或者 /search
|
||||
final Function? pageContentBuilder =
|
||||
routes[name]; // Function = (contxt) { return const NewsPage()}
|
||||
|
||||
if (pageContentBuilder != null) {
|
||||
if (settings.arguments != null) {
|
||||
final Route route = CupertinoPageRoute(
|
||||
settings: settings,
|
||||
builder: (context) =>
|
||||
pageContentBuilder(context, arguments: settings.arguments));
|
||||
return route;
|
||||
} else {
|
||||
final Route route = CupertinoPageRoute(
|
||||
settings: settings,
|
||||
builder: (context) => pageContentBuilder(context));
|
||||
|
||||
return route;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user