初始化项目
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,
|
||||
};
|
||||
Reference in New Issue
Block a user