This commit is contained in:
wyf
2025-05-24 17:02:47 +08:00
parent acfb262812
commit 3d45b7d991
22 changed files with 2990 additions and 1649 deletions

View File

@@ -132,7 +132,7 @@
"wifi页":{
"标题":"WIFI配置",
"跳过":"跳过",
"WLAN":"WLAN",
"WLAN":"网络",
"未连接":"未连接",
"已连接":"已连接",
"可用WLAN":"可用WLAN",
@@ -307,7 +307,7 @@
"搜索":"搜索",
"名称":"名称:",
"账号":"账号:",
"分享时间":"分享时间",
"分享时间":"分享时间",
"设备校准":"设备校准",
"离床校准":"离床校准",
"未完成":"未完成",
@@ -367,5 +367,11 @@
"解绑":"解绑",
"删除":"删除",
"校准未完成提示":"校准还未完成,是否确认退出校准流程?",
"确定":"确定"
"确定":"确定",
"查看":"查看",
"报修成功标题":"报修成功",
"报修成功":"报修成功!",
"查看报修历史":"查看报修历史",
"报修成功标语":"报修申请提交后,我们的后台客服人员会与您取得联系,请保持电话畅通,感谢您对本产品的支持!",
"问题描述字数限制":"问题描述字数超过限制"
}

View File

@@ -305,7 +305,7 @@
"搜索":"搜索",
"名称":"名稱:",
"账号":"賬號:",
"分享时间":"分享時間",
"分享时间":"分享時間",
"设备校准":"設備校準",
"离床校准":"離床校準",
"未完成":"未完成",

View File

@@ -176,7 +176,6 @@ class MyUtils {
return '$dateStr $weekStr';
}
}
Color stringToColor(String hexColor) {
@@ -313,11 +312,16 @@ var returnIconButtom = IconButton(
icon: Icon(Icons.navigate_before, size: 60.rpx),
);
var returnIconButtomAddCallback = (returnCallBack) {
var returnIconButtomAddCallback = (
VoidCallback? returnCallBack, {
bool enableBack = true,
}) {
return IconButton(
onPressed: () {
returnCallBack?.call();
if (enableBack) {
Get.back();
}
},
icon: Icon(Icons.navigate_before, size: 60.rpx),
);

View File

@@ -40,7 +40,7 @@ class RepairController extends GetControllerEx<RepairModel> {
attr = GetModel(RepairModel()).obs;
}
RxString device_type = "".obs;
RxDouble device_type = 0.0.obs;
RxList repairList = [].obs;
RxString name = "".obs;

View File

@@ -63,7 +63,6 @@ Future<void> main() async {
await initLog();
await messageStatus();
startMessagePolling();
// 检查网络
Checknetwork.checkNetwork();
@@ -93,7 +92,7 @@ Future<void> initWX() async {
appId: "wxeb2688220799e2c5",
doOnAndroid: true,
doOnIOS: true,
);
universalLink: "https://app.he-info.com/theh/");
}
Timer? _messageTimer;

View File

@@ -291,12 +291,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
});
_popupEntry?.remove();
_popupEntry = null;
dealWifi(widget.device['mac']);
dealWifi(widget.device);
},
),
_buildMenuItem(
text: "设备校准".tr,
onTap: () {
onTap: () async {
setState(() {
_isPopupOpen = false;
});
@@ -305,7 +305,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
BlueteethBindController blueteethBindController = Get.find();
blueteethBindController.currentDeviceMac?.value =
widget.device['mac'];
Get.toNamed("/calibrationPage", arguments: 2);
await Get.toNamed("/calibrationPage", arguments: 2);
},
),
_buildMenuItem(
@@ -848,11 +848,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
),
);
},
child: SvgPicture.asset(
'assets/img/icon/signal${widget.device['status']['wifi']}.svg',
width: 25.rpx,
height: 25.rpx,
fit: BoxFit.fill,
child: Container(
width: 30.rpx,
height: 24.rpx,
child: Image.asset(
'assets/img/signal${_getSignalLevel(widget.device['status']['signal'])}.png'),
),
),
if (widget.device['status']['inBed'] != null &&
@@ -860,10 +861,10 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
widget.device['status']['status'] == 1)
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.grey, // 可根据需要更换颜色
highlightColor: Colors.grey,
padding:
EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
borderRadius: 0, // 如果你希望圆角可修改
borderRadius: 0,
onTap: () {
showTipDialog(
context,
@@ -1285,149 +1286,149 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
return "未知数据".tr;
}
Future<void> dealWifi(String mac) async {
bodyDeviceController.wifiMac = mac;
Get.toNamed("/wifiPage", arguments: mac);
Future<void> dealWifi(device) async {
bodyDeviceController.wifiMac = device['mac'];
Get.toNamed("/wifiPage", arguments: device);
return;
final blueteethBindController = Get.find<BlueteethBindController>();
final themeController = Get.find<ThemeController>();
// final blueteethBindController = Get.find<BlueteethBindController>();
// final themeController = Get.find<ThemeController>();
// 显示加载对话框
showLoadingDialog(Get.context!, title: "连接中...".tr);
// // 显示加载对话框
// showLoadingDialog(Get.context!, title: "连接中...".tr);
// 设置超时定时器
Timer? timeoutTimer;
bool isConnected = false;
// // 设置超时定时器
// Timer? timeoutTimer;
// bool isConnected = false;
try {
// 开始扫描蓝牙设备
await FlutterBluePlus.startScan(timeout: Duration(seconds: 10));
// try {
// // 开始扫描蓝牙设备
// await FlutterBluePlus.startScan(timeout: Duration(seconds: 10));
// 设置超时20秒
timeoutTimer = Timer(Duration(seconds: 20), () {
try {
if (!isConnected) {
Navigator.of(context).pop(); // 先关闭 dialog
WidgetsBinding.instance.addPostFrameCallback((_) {
TopSlideNotification.show(
context,
text: "设备连接超时,请重试".tr,
textColor: themeController.currentColor.sc9,
);
});
FlutterBluePlus.stopScan();
}
} catch (e) {
print(e);
}
});
// 监听扫描结果
StreamSubscription<List<ScanResult>>? scanSubscription;
scanSubscription = FlutterBluePlus.scanResults.listen((results) async {
// 过滤出符合条件的设备
ScanResult? targetDevice;
for (var r in results) {
if (r.advertisementData.manufacturerData.containsKey(0xFFED)) {
List<int> rawData = r.advertisementData.manufacturerData[0xFFED]!;
BleDeviceData deviceData = parseBleData(rawData);
String deviceMac =
deviceData.deviceId.replaceAll(':', '').toLowerCase();
if (deviceMac == mac.toLowerCase()) {
targetDevice = r;
break;
}
}
}
if (targetDevice != null && !isConnected) {
isConnected = true;
FlutterBluePlus.stopScan();
scanSubscription?.cancel();
timeoutTimer?.cancel();
try {
// 连接设备
// await targetDevice.device.connect();
THapp bledevice = THapp(device: targetDevice.device);
await bledevice.device.connect();
var res2 = bledevice.isConnected;
if (res2) {
Navigator.pop(context);
TopSlideNotification.show(
context,
text: "蓝牙绑定.连接成功".tr,
textColor: themeController.currentColor.sc2,
);
blueteethBindController.currentDevice = bledevice;
if (lisObj != null) {
lisObj!.cancel();
}
var aa;
lisObj = blueteethBindController.currentDevice!.statusStream
.listen((onData) async {
if (onData.status == BleEventType.recvLineLog) {
final line = onData.val;
print("[bleee]:" + line);
}
if (onData.status == BleEventType.ready) {
aa = await getDeviceNetVersion(
blueteethBindController.currentDevice!, 1);
if (aa == "4g") {
// // 设置超时20秒
// timeoutTimer = Timer(Duration(seconds: 20), () {
// try {
// if (!isConnected) {
// Navigator.of(context).pop(); // 先关闭 dialog
// WidgetsBinding.instance.addPostFrameCallback((_) {
// TopSlideNotification.show(
// Get.context!,
// context,
// text: "设备连接超时,请重试".tr,
// textColor: themeController.currentColor.sc9,
// );
// });
// FlutterBluePlus.stopScan();
// }
// } catch (e) {
// print(e);
// }
// });
// // 监听扫描结果
// StreamSubscription<List<ScanResult>>? scanSubscription;
// scanSubscription = FlutterBluePlus.scanResults.listen((results) async {
// // 过滤出符合条件的设备
// ScanResult? targetDevice;
// for (var r in results) {
// if (r.advertisementData.manufacturerData.containsKey(0xFFED)) {
// List<int> rawData = r.advertisementData.manufacturerData[0xFFED]!;
// BleDeviceData deviceData = parseBleData(rawData);
// String deviceMac =
// deviceData.deviceId.replaceAll(':', '').toLowerCase();
// if (deviceMac == mac.toLowerCase()) {
// targetDevice = r;
// break;
// }
// }
// }
// if (targetDevice != null && !isConnected) {
// isConnected = true;
// FlutterBluePlus.stopScan();
// scanSubscription?.cancel();
// timeoutTimer?.cancel();
// try {
// // 连接设备
// // await targetDevice.device.connect();
// THapp bledevice = THapp(device: targetDevice.device);
// await bledevice.device.connect();
// var res2 = bledevice.isConnected;
// if (res2) {
// Navigator.pop(context);
// TopSlideNotification.show(
// context,
// text: "蓝牙绑定.连接成功".tr,
// textColor: themeController.currentColor.sc2,
// );
// blueteethBindController.currentDevice = bledevice;
// if (lisObj != null) {
// lisObj!.cancel();
// }
// var aa;
// lisObj = blueteethBindController.currentDevice!.statusStream
// .listen((onData) async {
// if (onData.status == BleEventType.recvLineLog) {
// final line = onData.val;
// print("[bleee]:" + line);
// }
// if (onData.status == BleEventType.ready) {
// aa = await getDeviceNetVersion(
// blueteethBindController.currentDevice!, 1);
// if (aa == "4g") {
// // TopSlideNotification.show(
// // Get.context!,
// // text: "4g设备配置wifi提示".tr,
// // textColor: themeController.currentColor.sc9,
// // );
// WidgetsBinding.instance.addPostFrameCallback((_) {
// TopSlideNotification.show(
// context,
// text: "4g设备配置wifi提示".tr,
// textColor: themeController.currentColor.sc9,
// );
WidgetsBinding.instance.addPostFrameCallback((_) {
TopSlideNotification.show(
context,
text: "4g设备配置wifi提示".tr,
textColor: themeController.currentColor.sc9,
);
});
return;
} else {
Get.toNamed("/wifiPage", arguments: 2);
}
}
});
// });
// return;
// } else {
// Get.toNamed("/wifiPage", arguments: 2);
// }
// }
// });
// Get.toNamed("/wifiPage", arguments: {bledevice});
} else {
Navigator.pop(context);
TopSlideNotification.show(
context,
text: "蓝牙绑定.连接失败".tr,
textColor: themeController.currentColor.sc9,
);
}
} catch (e) {
Navigator.of(Get.context!).pop(); // 关闭加载对话框
TopSlideNotification.show(
Get.context!,
text: "设备连接失败".tr,
textColor: themeController.currentColor.sc9,
);
}
}
});
// // Get.toNamed("/wifiPage", arguments: {bledevice});
// } else {
// Navigator.pop(context);
// TopSlideNotification.show(
// context,
// text: "蓝牙绑定.连接失败".tr,
// textColor: themeController.currentColor.sc9,
// );
// }
// } catch (e) {
// Navigator.of(Get.context!).pop(); // 关闭加载对话框
// TopSlideNotification.show(
// Get.context!,
// text: "设备连接失败".tr,
// textColor: themeController.currentColor.sc9,
// );
// }
// }
// });
// 等待扫描完成
await Future.delayed(Duration(seconds: 20));
} catch (e) {
timeoutTimer?.cancel();
Navigator.of(Get.context!).pop(); // 关闭加载对话框
TopSlideNotification.show(
Get.context!,
text: "扫描过程中发生错误".tr,
textColor: themeController.currentColor.sc9,
);
} finally {
timeoutTimer?.cancel();
await FlutterBluePlus.stopScan();
}
// // 等待扫描完成
// await Future.delayed(Duration(seconds: 20));
// } catch (e) {
// timeoutTimer?.cancel();
// Navigator.of(Get.context!).pop(); // 关闭加载对话框
// TopSlideNotification.show(
// Get.context!,
// text: "扫描过程中发生错误".tr,
// textColor: themeController.currentColor.sc9,
// );
// } finally {
// timeoutTimer?.cancel();
// await FlutterBluePlus.stopScan();
// }
}
double _calculateMaxMenuItemWidth(List<String> texts, TextStyle style) {
@@ -1448,6 +1449,18 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
return iconWidth + spacing + maxTextWidth + horizontalPadding;
}
int _getSignalLevel(int signal) {
if (signal <= 25) {
return 1;
} else if (signal <= 50) {
return 2;
} else if (signal <= 75) {
return 3;
} else {
return 4;
}
}
}
_showBluetoothNotEnabledDialog() async {

View File

@@ -85,7 +85,7 @@ class _EPageState extends State<BindDeviceSuccess> {
highlightColor: Colors
.grey, // 可以设置为 themeController.currentColor.sc3 之类
borderRadius: 8.rpx,
padding: EdgeInsets.all(0.rpx), // 增加可点击区域
padding: EdgeInsets.all(8.rpx), // 增加可点击区域
child: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
@@ -101,18 +101,19 @@ class _EPageState extends State<BindDeviceSuccess> {
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(113.rpx, 0, 113.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: bodySize.maxHeight * 0.15,
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 74.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
child: Container(
width: 124.rpx,
height: 124.rpx,
@@ -126,8 +127,7 @@ class _EPageState extends State<BindDeviceSuccess> {
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 42.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 42.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
@@ -148,8 +148,7 @@ class _EPageState extends State<BindDeviceSuccess> {
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 265.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 65.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
@@ -163,15 +162,14 @@ class _EPageState extends State<BindDeviceSuccess> {
fontFamily: 'Inter',
fontSize: 30.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
color: themeController.currentColor.sc4,
),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 48.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 48.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
@@ -183,17 +181,16 @@ class _EPageState extends State<BindDeviceSuccess> {
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 30.rpx,
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
color: themeController.currentColor.sc4,
),
),
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 110.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 110.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
@@ -266,8 +263,7 @@ class _EPageState extends State<BindDeviceSuccess> {
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0, 18.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(0, 18.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
@@ -315,54 +311,6 @@ class _EPageState extends State<BindDeviceSuccess> {
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
colors: [themeController.currentColor.sc17], // 背景色
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,
),
),
],
),
),
);
}
}

View File

@@ -98,14 +98,14 @@ class _BlueteethDevicePageState extends State<BlueteethDevicePage> {
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("权限提示"),
content: Text("应用需要蓝牙和位置权限才能扫描设备。请授予权限。"),
title: Text("权限提示".tr),
content: Text("应用需要蓝牙和位置权限才能扫描设备。请授予权限。".tr),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("确定"),
child: Text("确定".tr),
),
],
);

View File

@@ -414,6 +414,7 @@ void showConfirmDialog(
ThemeController themeController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
try {
showDialog(
context: context,
barrierDismissible: true,
@@ -577,8 +578,10 @@ void showConfirmDialog(
);
},
);
} catch (e) {
print(e);
}
}
void showSingleConfirmDialog(
BuildContext context,
@@ -667,7 +670,6 @@ void showSingleConfirmDialog(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomCard(
borderRadius: AppConstants().button_container_radius,
onTap: () {
@@ -706,7 +708,6 @@ void showSingleConfirmDialog(
),
),
),
].divide(SizedBox(
width: 70.rpx,
)),

View File

@@ -29,6 +29,7 @@ class _CalibrationPageState extends State<CalibrationPage> {
DeviceCalibrationController deviceCalibrationController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
int flag = 0; //默认没有开始校准过
bool exit = false;
@override
void initState() {
super.initState();
@@ -48,7 +49,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
return WillPopScope(
child: LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
@@ -63,7 +65,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
iconTheme:
IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
title: Container(
width: double.infinity,
@@ -82,7 +85,36 @@ class _CalibrationPageState extends State<CalibrationPage> {
),
Positioned(
left: 0,
child: returnIconButtom,
child: returnIconButtomAddCallback(() {
if (flag != 0) {
try {
showConfirmDialog(
context, Container(), "校准未完成提示".tr,
onConfirm: () async {
exit = true;
await Get.toNamed("/personPage");
print("object");
deviceCalibrationController.process.value = 0;
deviceCalibrationController
.bed_calibration.value = 0;
deviceCalibrationController
.position_calibration.value = 0;
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
}, onCancel: () {
exit = false;
});
} catch (e) {
print(e);
}
} else {
exit = true;
}
if (exit) {
Get.back();
}
},enableBack:exit ),
),
if (widget.type == 1)
Positioned(
@@ -96,13 +128,15 @@ class _CalibrationPageState extends State<CalibrationPage> {
onConfirm: () async {
await Get.toNamed("/personPage");
print("object");
deviceCalibrationController.process.value = 0;
deviceCalibrationController.process.value =
0;
deviceCalibrationController
.bed_calibration.value = 0;
deviceCalibrationController
.position_calibration.value = 0;
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
deviceCalibrationController.complete =
false;
}, onCancel: () {});
} else {
await Get.toNamed("/personPage");
@@ -154,8 +188,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 30.rpx, 0, 0),
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 30.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
@@ -190,7 +224,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
maintainState: true,
maintainAnimation: true,
maintainSize: true,
visible: deviceCalibrationController
visible:
deviceCalibrationController
.process.value ==
0,
child: SvgPicture.asset(
@@ -217,7 +252,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
Obx(() {
return Text(
deviceCalibrationController
.bed_calibration.value ==
.bed_calibration
.value ==
0
? '未完成'.tr
: "已完成".tr,
@@ -225,9 +261,11 @@ class _CalibrationPageState extends State<CalibrationPage> {
fontSize: 26.rpx,
letterSpacing: 0.0,
color: deviceCalibrationController
.bed_calibration.value ==
.bed_calibration
.value ==
0
? themeController.currentColor.sc3
? themeController
.currentColor.sc3
: themeController
.currentColor.sc1,
),
@@ -259,7 +297,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
maintainState: true,
maintainAnimation: true,
maintainSize: true,
visible: deviceCalibrationController
visible:
deviceCalibrationController
.process.value ==
1,
child: SvgPicture.asset(
@@ -298,7 +337,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
.position_calibration
.value ==
0
? themeController.currentColor.sc3
? themeController
.currentColor.sc3
: themeController
.currentColor.sc1,
),
@@ -323,10 +363,11 @@ class _CalibrationPageState extends State<CalibrationPage> {
clipBehavior: Clip.none,
children: [
Container(
width:
MediaQuery.sizeOf(context).width * 0.65,
width: MediaQuery.sizeOf(context).width *
0.65,
height:
MediaQuery.sizeOf(context).height * 0.3,
MediaQuery.sizeOf(context).height *
0.3,
child: Stack(
children: [
// Image.asset(
@@ -365,8 +406,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
// 床头文字
Positioned(
top: 23.rpx,
left:
(MediaQuery.sizeOf(context).width *
left: (MediaQuery.sizeOf(context)
.width *
0.65) /
2 -
26.rpx,
@@ -421,7 +462,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
//双人人床位置校准
return Positioned(
top: -40.rpx,
left: (MediaQuery.sizeOf(context).width *
left: (MediaQuery.sizeOf(context)
.width *
0.65) *
0.22 -
0.rpx,
@@ -446,7 +488,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
return Container();
}),
Positioned(
top: MediaQuery.sizeOf(context).height * 0.3 +
top: MediaQuery.sizeOf(context).height *
0.3 +
82.rpx,
left: 0,
right: 0,
@@ -455,14 +498,16 @@ class _CalibrationPageState extends State<CalibrationPage> {
children: [
Text(
(deviceCalibrationController
.process.value ==
.process
.value ==
0 &&
deviceCalibrationController
.bed_calibration
.value ==
1) ||
(deviceCalibrationController
.process.value ==
.process
.value ==
1 &&
deviceCalibrationController
.position_calibration
@@ -521,8 +566,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
showConfirmDialog(
context, Container(), "校准已经完成,是否重新开始校准?",
onConfirm: () {
BlueteethBindController blueteethBindController =
Get.find();
BlueteethBindController
blueteethBindController = Get.find();
deviceCalibrationController.process.value = 0;
deviceCalibrationController
.bed_calibration.value = 0;
@@ -558,7 +603,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
false;
if (isSecondStep) {
data["id"] = blueteethBindController.cid!.value;
data["id"] =
blueteethBindController.cid!.value;
}
// 发起校准请求
@@ -570,8 +616,10 @@ class _CalibrationPageState extends State<CalibrationPage> {
onSuccess: (res) {
if (!isSecondStep) {
// 保存第一次获取的 cid
String cid = res.rawResponse.data['cid'];
blueteethBindController.cid!.value = cid;
String cid =
res.rawResponse.data['cid'];
blueteethBindController.cid!.value =
cid;
}
void requestCalibrationProgress() {
@@ -587,12 +635,15 @@ class _CalibrationPageState extends State<CalibrationPage> {
final data = res.data;
double per =
(data['per'] ?? 0).toDouble();
int currStep = data['currStep'] ?? -1;
bool status = data['status'] ?? false;
String tips = data['statusText'] ?? '';
int currStep =
data['currStep'] ?? -1;
bool status =
data['status'] ?? false;
String tips =
data['statusText'] ?? '';
deviceCalibrationController.tips.value =
tips;
deviceCalibrationController
.tips.value = tips;
progressNotifier.value = per;
if (!isSecondStep && per >= 20) {
@@ -623,11 +674,12 @@ class _CalibrationPageState extends State<CalibrationPage> {
deviceCalibrationController
.bed_calibration.value = 1;
deviceCalibrationController
.position_calibration.value = 1;
.position_calibration
.value = 1;
deviceCalibrationController
.process.value = 1;
deviceCalibrationController.complete =
true;
deviceCalibrationController
.complete = true;
deviceCalibrationController
.updateAll();
}
@@ -638,8 +690,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
TopSlideNotification.show(
context,
text: res.msg ?? "服务器.失败".tr,
textColor:
themeController.currentColor.sc9,
textColor: themeController
.currentColor.sc9,
);
},
);
@@ -649,20 +701,21 @@ class _CalibrationPageState extends State<CalibrationPage> {
requestCalibrationProgress();
// 开始轮询
pollingTimer =
Timer.periodic(Duration(seconds: 2), (_) {
pollingTimer = Timer.periodic(
Duration(seconds: 2), (_) {
requestCalibrationProgress();
});
// 显示进度弹窗
showProgressDialog(context, progressNotifier,
failureNotifier);
showProgressDialog(context,
progressNotifier, failureNotifier);
},
onFailure: (res) {
TopSlideNotification.show(
context,
text: res.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
textColor:
themeController.currentColor.sc9,
);
},
);
@@ -670,8 +723,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
return;
});
} else {
BlueteethBindController blueteethBindController =
Get.find();
BlueteethBindController
blueteethBindController = Get.find();
String serviceAddress =
"https://caibration.he-info.cn";
String calibrationApi =
@@ -679,7 +732,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
String progressApi =
ServiceConstant.calibration_process;
String queryUrl = "$serviceAddress$calibrationApi";
String queryUrl =
"$serviceAddress$calibrationApi";
final ValueNotifier<double> progressNotifier =
ValueNotifier<double>(0.0);
@@ -693,12 +747,13 @@ class _CalibrationPageState extends State<CalibrationPage> {
};
// 是否是二次点击有cid表示进行第二阶段
bool isSecondStep =
blueteethBindController.cid?.value.isNotEmpty ??
bool isSecondStep = blueteethBindController
.cid?.value.isNotEmpty ??
false;
if (isSecondStep) {
data["id"] = blueteethBindController.cid!.value;
data["id"] =
blueteethBindController.cid!.value;
}
// 发起校准请求
@@ -729,10 +784,11 @@ class _CalibrationPageState extends State<CalibrationPage> {
(data['per'] ?? 0).toDouble();
int currStep = data['currStep'] ?? -1;
bool status = data['status'] ?? false;
String tips = data['statusText'] ?? '';
String tips =
data['statusText'] ?? '';
deviceCalibrationController.tips.value =
tips;
deviceCalibrationController
.tips.value = tips;
progressNotifier.value = per;
if (!isSecondStep && per >= 20) {
@@ -746,7 +802,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
deviceCalibrationController
.bed_calibration.value = 1;
deviceCalibrationController.updateAll();
deviceCalibrationController
.updateAll();
}
if (isSecondStep &&
@@ -764,9 +821,10 @@ class _CalibrationPageState extends State<CalibrationPage> {
.position_calibration.value = 1;
deviceCalibrationController
.process.value = 1;
deviceCalibrationController.complete =
true;
deviceCalibrationController.updateAll();
deviceCalibrationController
.complete = true;
deviceCalibrationController
.updateAll();
}
},
onFailure: (res) {
@@ -775,8 +833,8 @@ class _CalibrationPageState extends State<CalibrationPage> {
TopSlideNotification.show(
context,
text: res.msg ?? "服务器.失败".tr,
textColor:
themeController.currentColor.sc9,
textColor: themeController
.currentColor.sc9,
);
},
);
@@ -786,20 +844,21 @@ class _CalibrationPageState extends State<CalibrationPage> {
requestCalibrationProgress();
// 开始轮询
pollingTimer =
Timer.periodic(Duration(seconds: 2), (_) {
pollingTimer = Timer.periodic(
Duration(seconds: 2), (_) {
requestCalibrationProgress();
});
// 显示进度弹窗
showProgressDialog(
context, progressNotifier, failureNotifier);
showProgressDialog(context,
progressNotifier, failureNotifier);
},
onFailure: (res) {
TopSlideNotification.show(
context,
text: res.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
textColor:
themeController.currentColor.sc9,
);
},
);
@@ -827,10 +886,11 @@ class _CalibrationPageState extends State<CalibrationPage> {
.bodyMedium
.override(
//todo 颜色
color: themeController.currentColor.sc3,
color:
themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize:
AppConstants().normal_text_fontSize,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
@@ -848,6 +908,27 @@ class _CalibrationPageState extends State<CalibrationPage> {
),
),
),
);
),
onWillPop: () async {
bool exit = false;
if (flag != 0) {
showConfirmDialog(context, Container(), "校准未完成提示".tr,
onConfirm: () async {
exit = true;
await Get.toNamed("/personPage");
print("object");
deviceCalibrationController.process.value = 0;
deviceCalibrationController.bed_calibration.value = 0;
deviceCalibrationController.position_calibration.value = 0;
blueteethBindController.cid!.value = "";
deviceCalibrationController.complete = false;
}, onCancel: () {
exit = false;
});
} else {
exit = true;
}
return exit;
});
}
}

View File

@@ -46,8 +46,11 @@ class _WifiPageState extends State<WifiPage> {
blueteethBindController.wifiStatus = 0.obs;
blueteethBindController.connect_wifi.value = {};
blueteethBindController.selectWifi.value = {};
if (widget.type == null) {
if (widget.type != null) {
blueteethBindController.wifiStatus.value =
widget.type['status']['status'];
}
if (widget.type['mac'] == null) {
THapp bledevice = blueteethBindController.currentDevice!;
bledevice.device.connect().then((Value) {
var res2 = bledevice.isConnected;
@@ -85,11 +88,18 @@ class _WifiPageState extends State<WifiPage> {
Get.toNamed("/calibrationPage", arguments: 1);
});
} else if (aa == 'unknown') {
// TopSlideNotification.show(
// context,
// text: "获取设备网络类型失败".tr,
// textColor: themeController.currentColor.sc9,
// );
WidgetsBinding.instance.addPostFrameCallback((_) {
TopSlideNotification.show(
context,
text: "获取设备网络类型失败".tr,
textColor: themeController.currentColor.sc9,
);
});
} else {
await initWifiStatusAndWifiList();
}
@@ -106,7 +116,7 @@ class _WifiPageState extends State<WifiPage> {
}
});
} else {
dealWifi(widget.type).then((aa) {
dealWifi(widget.type['mac']).then((aa) {
print("object");
});
}
@@ -188,7 +198,7 @@ class _WifiPageState extends State<WifiPage> {
left: 0,
child: returnIconButtom,
),
if (widget.type == null)
if (widget.type['mac'] == null)
Positioned(
right: 20.rpx,
child: CustomCard(

View File

@@ -505,10 +505,11 @@ class _EPageState extends State<LoginPage> {
// text: "待开发功能".tr);
// },
onTap: () async {
if (loginController.model.isIos == true &&
loginController
//loginController.model.isIos == true &&
if (loginController
.model.isWeChatNotInstalled !=
true) {
TopSlideNotification.show(context,text: "微信安装提示".tr,textColor: themeController.currentColor.sc9);
} else {
if (loginController
.model.register_agree ==

View File

@@ -825,9 +825,33 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
highlightColor: Colors.grey, // 点击水波纹颜色
borderRadius: 999.rpx,
padding: EdgeInsets.zero,
onTap: () {
onTap: () async {
//loginController.model.isIos == true &&
if (loginController
.model.isWeChatNotInstalled !=
true) {
TopSlideNotification.show(context,
text: "待开发功能".tr);
text: "微信安装提示".tr,
textColor:
themeController.currentColor.sc9);
} else {
if (loginController
.model.register_agree ==
null ||
loginController
.model.register_agree !=
true) {
TopSlideNotification.show(
context,
text: "登录页.未同意协议".tr,
textColor:
themeController.currentColor.sc9,
);
return;
}
await loginController
.wxLoginSendAuth(context);
}
},
child: Container(
width: 91.rpx,

View File

@@ -153,6 +153,7 @@ class _MessageWidgetWidgetState extends State<MessageWidgetWidget> {
),
),
),
],
);
}

View File

@@ -63,7 +63,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
await deviceTypeController.getDeviceType(); // 等待数据加载
if (deviceTypeController.deviceTypeList.isNotEmpty) {
repairController.device_type.value =
deviceTypeController.deviceTypeList.first['_id'];
deviceTypeController.deviceTypeList.first['type'];
}
await bodyDeviceController.getDeviceList();
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -80,7 +80,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
Widget build(BuildContext context) {
if (deviceTypeController.deviceTypeList.isNotEmpty) {
repairController.device_type.value =
deviceTypeController.deviceTypeList.first['_id'];
deviceTypeController.deviceTypeList.first['type'];
}
if (bodyDeviceController.deviceList.isNotEmpty) {
repairController.deviceListId = bodyDeviceController.deviceList
@@ -169,7 +169,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
AppConstants().button_container_radius,
onTap: () async {
repairController.device_type.value =
deviceType['_id'];
deviceType['type'];
repairController.repairList
.clear(); // 清空旧数据
repairController.repairList
@@ -180,7 +180,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
repairController
.updateAll(); // 手动触发更新(如果未自动更新)
},
colors: deviceType['_id'] ==
colors: deviceType['type'] ==
repairController.device_type.value
? [
themeController.currentColor.sc1,
@@ -328,7 +328,7 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
String queryUrl =
"$serviceAddress$serviceName$serviceApi";
var data = {
"device": repairController.repairList,
"device": repairController.repairList.value,
"type": repairController.device_type.value,
"contacts": {
"name": repairController.name.value,
@@ -340,8 +340,19 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
method: MyHttpMethod.post,
queryUrl: queryUrl,
data: data,
onSuccess: (res) {
TopSlideNotification.show(context,
text: res.msg!);
// Get.back();
Get.toNamed("/applyRepairSuccess");
},
onFailure: (res) {
TopSlideNotification.show(context,
text: res.msg!,
textColor:
themeController.currentColor.sc9);
},
);
Get.back();
}
},
colors: [
@@ -515,16 +526,32 @@ class _ApplyRepairPageState extends State<ApplyRepairPage> {
// return "第 ${i + 1} 项问题描述未填写";
return "问题描述未填写".tr;
}
if (item["issue"] != null && item["issue"].toString().trim().isNotEmpty) {
final issueText = item["issue"].toString().trim();
final charCount = issueText.runes.length;
if (charCount > 60) {
_scrollToKey(repairItemKeys[i]);
return "问题描述最多输入60个字".tr;
}
} else {
_scrollToKey(repairItemKeys[i]);
return "问题描述不能为空".tr;
}
}
// 检查联系人
if (repairController.name.trim().isEmpty) {
_scrollToKey(contactKey);
return "联系人不能为空";
return "联系人不能为空".tr;
}
if (repairController.phone.trim().isEmpty) {
_scrollToKey(phoneKey);
return "联系电话不能为空";
return "联系电话不能为空".tr;
}
if (!MyUtils.isValidPhoneNumber(repairController.phone.trim())) {
_scrollToKey(phoneKey);
return "无效的手机号码".tr;
}
return errormsg;

View File

@@ -0,0 +1,347 @@
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/component/tool/ClickableContainer.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/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
class ApplyRepairSuccess extends StatefulWidget {
const ApplyRepairSuccess({super.key});
@override
State<ApplyRepairSuccess> createState() => _ApplyRepairSuccessState();
}
class _ApplyRepairSuccessState extends State<ApplyRepairSuccess> {
GlobalController globalController = Get.find();
UserInfoController userInfoController = Get.find();
BlueteethBindController blueteethBindController = Get.find();
ThemeController themeController = Get.find();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent, // 加上这一行
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
titleSpacing: 0,
// leading: returnIconButtom,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
/// 居中标题
Text(
'报修成功标题'.tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
/// 左边返回按钮
// Positioned(
// left: 0,
// child: returnIconButtom,
// ),
Positioned(
left: 40.rpx,
child: ClickableContainer(
onTap: () {
Get.offAllNamed("/mianPageBottomChange");
},
backgroundColor: Colors.transparent,
highlightColor: Colors
.grey, // 可以设置为 themeController.currentColor.sc3 之类
borderRadius: 8.rpx,
padding: EdgeInsets.all(8.rpx), // 增加可点击区域
child: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
height: 25.rpx,
color: themeController.currentColor.sc3,
),
),
),
],
),
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(113.rpx, 0, 113.rpx, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Container(
height: bodySize.maxHeight * 0.15,
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0),
child: Container(
width: 124.rpx,
height: 124.rpx,
// width: double.infinity,
decoration: BoxDecoration(),
child: SvgPicture.asset(
'assets/img/icon/tick.svg',
fit: BoxFit.cover,
color: themeController.currentColor.sc3,
),
),
),
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(20.rpx, 42.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
'报修成功'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 48.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
),
),
),
),
SizedBox(
height: 90.rpx,
),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 265.rpx, 0, 0),
// child: Container(
// width: double.infinity,
// decoration: BoxDecoration(),
// child: Align(
// alignment: AlignmentDirectional(0, 0),
// child: Text(
// '绑定成功.分享标题'.tr,
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// fontSize: 30.rpx,
// letterSpacing: 0.0,
// color: themeController.currentColor.sc3,
// ),
// ),
// ),
// ),
// ),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 48.rpx, 0, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'报修成功标语'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 110.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () async {
Get.toNamed("/repairListPage");
},
colors: [
// 渐变色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
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: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 2.rpx, 0, 0),
child: SvgPicture.asset(
'assets/img/icon/history.svg',
width: 25.rpx,
height: 25.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: Colors.white,
),
),
Text(
'查看报修历史'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 18.rpx, 0, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
Get.offAllNamed("/mianPageBottomChange");
},
colors: [
// 渐变色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
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: [
Text(
'绑定成功.返回'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc3,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize, // 自定义字体大小
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
),
],
),
),
),
),
),
),
);
}
Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required String type}) {
return CustomCard(
borderRadius: 20.rpx, // 圆角大小
onTap: () {
if (type != null) {
if (type == '1') {
Get.toNamed("/blueteethDevice");
}
}
},
colors: [themeController.currentColor.sc17], // 背景色
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,
),
),
],
),
),
);
}
}

View File

@@ -1,15 +1,15 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/routers/routers.dart';
class RepairHistoryInfoWidget extends StatefulWidget {
const RepairHistoryInfoWidget({super.key});
var data;
RepairHistoryInfoWidget({super.key, required this.data});
@override
State<RepairHistoryInfoWidget> createState() =>
@@ -29,7 +29,9 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
@override
Widget build(BuildContext context) {
return ClickableContainer(
return Stack(
children: [
ClickableContainer(
borderRadius: AppConstants().normal_container_radius,
onTap: () {
//跳转详情
@@ -63,14 +65,14 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.14,
width: MediaQuery.sizeOf(context).width * 0.17,
constraints: BoxConstraints(
maxWidth: 130.rpx,
maxWidth: 140.rpx,
),
decoration: BoxDecoration(),
child: Text(
'设备类型'.tr,
maxLines: 2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -86,8 +88,8 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
),
),
Text(
'智能床',
maxLines: 2,
'${widget.data['type']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -95,8 +97,9 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
fontWeight: FlutterFlowTheme.of(context)
.bodyMedium
.fontWeight,
fontStyle:
FlutterFlowTheme.of(context).bodyMedium.fontStyle,
fontStyle: FlutterFlowTheme.of(context)
.bodyMedium
.fontStyle,
color: themeController.currentColor.sc3,
),
),
@@ -110,14 +113,14 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.14,
width: MediaQuery.sizeOf(context).width * 0.17,
constraints: BoxConstraints(
maxWidth: 130.rpx,
maxWidth: 140.rpx,
),
decoration: BoxDecoration(),
child: Text(
'设备ID'.tr,
maxLines: 2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -132,9 +135,10 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
),
),
),
Text(
'15561651',
maxLines: 2,
Expanded(
child: Text(
'${getDeviceInfo(widget.data)}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -142,11 +146,13 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
fontWeight: FlutterFlowTheme.of(context)
.bodyMedium
.fontWeight,
fontStyle:
FlutterFlowTheme.of(context).bodyMedium.fontStyle,
fontStyle: FlutterFlowTheme.of(context)
.bodyMedium
.fontStyle,
color: themeController.currentColor.sc3,
),
),
),
].divide(SizedBox(width: 33.rpx)),
),
),
@@ -157,14 +163,14 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.14,
width: MediaQuery.sizeOf(context).width * 0.17,
constraints: BoxConstraints(
maxWidth: 130.rpx,
maxWidth: 140.rpx,
),
decoration: BoxDecoration(),
child: Text(
'联系人'.tr,
maxLines: 2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -180,8 +186,8 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
),
),
Text(
'王明',
maxLines: 2,
'${widget.data['contacts']?['name']}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -189,8 +195,9 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
fontWeight: FlutterFlowTheme.of(context)
.bodyMedium
.fontWeight,
fontStyle:
FlutterFlowTheme.of(context).bodyMedium.fontStyle,
fontStyle: FlutterFlowTheme.of(context)
.bodyMedium
.fontStyle,
color: themeController.currentColor.sc3,
),
),
@@ -204,14 +211,14 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.14,
width: MediaQuery.sizeOf(context).width * 0.17,
constraints: BoxConstraints(
maxWidth: 130.rpx,
maxWidth: 140.rpx,
),
decoration: BoxDecoration(),
child: Text(
'发生时间'.tr,
maxLines: 2,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -227,8 +234,8 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
),
),
Text(
'2022-08-01 15:05',
maxLines: 2,
'${MyUtils.timestampToDateString(widget.data['create_time'])}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 26.rpx,
@@ -236,8 +243,9 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
fontWeight: FlutterFlowTheme.of(context)
.bodyMedium
.fontWeight,
fontStyle:
FlutterFlowTheme.of(context).bodyMedium.fontStyle,
fontStyle: FlutterFlowTheme.of(context)
.bodyMedium
.fontStyle,
color: themeController.currentColor.sc3,
),
),
@@ -249,6 +257,55 @@ class _RepairHistoryInfoWidgetState extends State<RepairHistoryInfoWidget> {
),
),
),
),
Positioned(
bottom: 40.rpx,
right: 20.rpx,
child: Container(
width: 123.rpx,
height: 47.rpx,
child: CustomCard(
borderRadius: AppConstants().button_container_radius, // 直角
colors: [
themeController.currentColor.sc4.withOpacity(0.3),
],
enableAnimation: true, // 有点击缩放动画
enableGradient: false, // 不用渐变
onTap: () {
Get.toNamed("/repairDetailPage", arguments: widget.data);
},
child: Center(
child: Text(
"查看".tr,
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Inter',
fontSize: 26.rpx,
letterSpacing: 0.0,
color: Colors.white,
),
),
),
),
),
),
],
);
}
String getDeviceInfo(Map data) {
if (data['device'] == null || data['device'] is! List) {
return '';
}
List deviceList = data['device'];
List<String> result = deviceList.map((device) {
final name = device['name'] ?? '';
final code = device['code'];
final mac = device['mac'] ?? '';
final suffix = (code != null && code.toString().isNotEmpty) ? code : mac;
return '$name($suffix)';
}).toList();
return result.join(', ');
}
}

View File

@@ -0,0 +1,489 @@
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/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
class RepairModelReadOnlyWidget extends StatefulWidget {
var model;
final VoidCallback onTap; // 添加回调函数
int length;
final GlobalKey widgetKey; // 新增
final bool showDelete; // ✅ 新增
RepairModelReadOnlyWidget({
super.key,
required this.model,
required this.onTap,
required this.length,
required this.widgetKey,
this.showDelete = true, // ✅ 默认为 false
});
@override
State<RepairModelReadOnlyWidget> createState() =>
_RepairModelReadOnlyWidgetState();
}
class _RepairModelReadOnlyWidgetState extends State<RepairModelReadOnlyWidget> {
FormFieldController<String> _deviceController =
FormFieldController<String>(null);
RepairController repairController = Get.find();
UserInfoController userInfoController = Get.find();
late FormFieldController<String?>? _issueController;
BodyDeviceController bodyDeviceController = Get.find();
@override
void setState(VoidCallback callback) {
super.setState(callback);
}
@override
void initState() {
super.initState();
_issueController =
FormFieldController<String?>(widget.model['issue'] ?? '');
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
key: widget.widgetKey, // 使用传入的 key
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius:
BorderRadius.circular(AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 35.rpx, 30.rpx, 35.rpx),
child: Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 110.rpx,
decoration: BoxDecoration(),
child: Text(
'设备ID'.tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc4,
),
),
),
Obx(() {
return Expanded(
child: Container(
width: 200.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.rpx),
color: Colors.transparent,
),
child: TextFormField(
readOnly: true,
controller: repairController.onReDraw(
TextEditingController(text: widget.model['id']),
(textEditingController) {
textEditingController.text = widget.model['id'];
}),
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle: TextStyle(
letterSpacing: 0.0,
fontWeight: FlutterFlowTheme.of(context)
.labelMedium
.fontWeight,
fontStyle: FlutterFlowTheme.of(context)
.labelMedium
.fontStyle,
),
hintText: "设备参数提示".tr,
hintStyle: TextStyle(
letterSpacing: 0.0,
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
fillColor: themeController.currentColor.sc15,
),
style: TextStyle(
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
cursorColor: themeController.currentColor.sc4,
onChanged: (value) {
widget.model['id'] = value;
},
),
),
);
}),
].divide(SizedBox(width: 24.rpx)),
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 110.rpx,
decoration: BoxDecoration(),
child: Text(
'设备参数'.tr,
style: TextStyle(
fontSize: 26.rpx,
color: themeController.currentColor.sc4,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Obx(() {
return Expanded(
child: Container(
width: 200.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.rpx),
color: Colors.transparent,
),
child: TextFormField(
readOnly: true,
controller: repairController.onReDraw(
TextEditingController(
text: widget.model['param']),
(textEditingController) {
textEditingController.text =
widget.model['param'];
}),
// initialValue: widget.model['param'],
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle: TextStyle(
letterSpacing: 0.0,
fontWeight: FlutterFlowTheme.of(context)
.labelMedium
.fontWeight,
fontStyle: FlutterFlowTheme.of(context)
.labelMedium
.fontStyle,
),
hintText: "设备参数提示".tr,
hintStyle: TextStyle(
letterSpacing: 0.0,
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1.rpx,
),
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1.rpx,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
fillColor: themeController.currentColor.sc15,
),
style: TextStyle(
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
cursorColor: themeController.currentColor.sc4,
onChanged: (value) {
widget.model['param'] = value;
},
),
),
);
}),
].divide(SizedBox(width: 24.rpx)),
),
),
Container(
width: double.infinity,
height: 151.rpx,
decoration: BoxDecoration(
color: themeController.currentColor.sc15,
borderRadius: BorderRadius.circular(20.rpx),
),
child: Container(
width: 200.rpx,
child: TextFormField(
readOnly: true,
controller: repairController.onReDraw(
TextEditingController(text: widget.model['issue']),
(textEditingController) {
textEditingController.text = widget.model['issue'];
}),
onChanged: (value) {
widget.model['issue'] = value;
},
maxLines: null, // 👈 支持无限行
// controller: TextEditingController(),
autofocus: false,
obscureText: false,
decoration: InputDecoration(
isDense: true,
labelStyle: TextStyle(
letterSpacing: 0.0,
fontWeight:
FlutterFlowTheme.of(context).labelMedium.fontWeight,
fontStyle:
FlutterFlowTheme.of(context).labelMedium.fontStyle,
),
hintText: '问题描述'.tr,
hintStyle: TextStyle(
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0x00000000),
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterFlowTheme.of(context).error,
width: 1,
),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: false,
contentPadding: EdgeInsets.symmetric(
vertical: 20.rpx, horizontal: 20.rpx),
),
style: TextStyle(
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
cursorColor: themeController.currentColor.sc4,
),
),
),
ClickableContainer(
backgroundColor: themeController.currentColor.sc15,
highlightColor: themeController.currentColor.sc21,
borderRadius: 20.rpx,
padding: EdgeInsets.zero,
onTap: () async {
ApiResponse apiResponse = await repairController.uploadImg();
print(apiResponse);
if (apiResponse.code == HttpStatusCodes.ok) {
print(widget.model);
// setState(() {
// widget.model['path'] = apiResponse.data['path'];
// });
widget.model['path'] = apiResponse.data['path'];
repairController.repairList
.refresh(); // 通知 Obx 更新(如果用了 GetX
print(widget.model);
} else {
if (widget.model['path'] == null ||
widget.model['path'].isEmpty) {
TopSlideNotification.show(
context,
text: apiResponse.msg!,
textColor: apiResponse.code == HttpStatusCodes.ok
? themeController.currentColor.sc2
: themeController.currentColor.sc9,
);
}
}
},
child: SizedBox(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.203,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 151.rpx,
),
child: Obx(() {
var list = repairController.repairList;
print(list);
if (widget.model['path'] == null ||
widget.model['path'] == "") {
return Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 60.rpx,
height: 53.rpx,
child: SvgPicture.asset(
'assets/img/icon/camera.svg',
width: 24.rpx,
height: 24.rpx,
color: themeController.currentColor.sc4,
),
),
Text(
'上传提示'.tr,
style: TextStyle(
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
),
),
].divide(SizedBox(height: 28.rpx)),
);
}
return Container(
// clipBehavior: Clip.antiAlias,
child: Image.network(
widget.model['path'],
fit: BoxFit.cover,
),
);
})),
),
),
if (widget.length > 1 && widget.showDelete == true)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
100.rpx, 0.rpx, 100.rpx, 0.rpx),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: widget.onTap,
colors: [
Colors.transparent,
],
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
AppConstants().button_container_radius),
),
width: MediaQuery.sizeOf(context).width * 0.216,
height: MediaQuery.sizeOf(context).height * 0.038,
constraints: BoxConstraints(
minHeight: 62.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'删除'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController.currentColor.sc9,
fontFamily: 'Inter',
fontSize: AppConstants().normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
].divide(SizedBox(height: 29.rpx)),
),
),
),
);
}
}

View File

@@ -5,26 +5,30 @@ import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/base/THFlutterFlowDropDown.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/routers/routers.dart';
class RepairModelWidget extends StatefulWidget {
var model;
final VoidCallback onTap; // 添加回调函数
int length;
final GlobalKey widgetKey; // 新增
final bool showDelete; // ✅ 新增
RepairModelWidget({
super.key,
required this.model,
required this.onTap,
required this.length,
required this.widgetKey,
this.showDelete = true, // ✅ 默认为 false
});
@override
@@ -36,6 +40,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
FormFieldController<String>(null);
RepairController repairController = Get.find();
UserInfoController userInfoController = Get.find();
late FormFieldController<String?>? _issueController;
BodyDeviceController bodyDeviceController = Get.find();
@override
void setState(VoidCallback callback) {
@@ -45,6 +51,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
@override
void initState() {
super.initState();
_issueController =
FormFieldController<String?>(widget.model['issue'] ?? '');
}
@override
@@ -54,7 +62,6 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
@override
Widget build(BuildContext context) {
// _deviceController.value = "";
return Container(
key: widget.widgetKey, // 使用传入的 key
width: double.infinity,
@@ -97,8 +104,31 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
),
height: AppConstants().dropdown_height,
child: THFlutterFlowDropDown<String>(
controller: _issueController,
onChanged: (val) {
widget.model['id'] = val;
final targetId = widget.model['id'];
final matchedDevice =
bodyDeviceController.deviceList.firstWhere(
(device) => device['_id'] == targetId,
orElse: () => null, // 如果找不到,返回 null可选
);
if (matchedDevice != null) {
// 找到了匹配的项
widget.model['param'] = matchedDevice['mac'];
widget.model['mac'] = matchedDevice['mac'];
widget.model['code'] =
matchedDevice['code'] ?? '';
widget.model['name'] = (matchedDevice['person']
?['name']
?.toString()
.trim()
.isNotEmpty ??
false)
? matchedDevice['person']['name']
: '未命名'.tr;
repairController.updateAll();
}
},
width: 200.rpx,
height: 40.rpx,
@@ -127,7 +157,7 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
isOverButton: false,
isSearchable: false,
isMultiSelect: false,
controller: _deviceController,
// controller: _deviceController,
options: repairController.deviceListId!,
optionLabels: repairController.deviceListId!,
),
@@ -155,7 +185,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
overflow: TextOverflow.ellipsis,
),
),
Expanded(
Obx(() {
return Expanded(
child: Container(
width: 200.rpx,
decoration: BoxDecoration(
@@ -167,7 +198,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
TextEditingController(
text: widget.model['param']),
(textEditingController) {
textEditingController.text = widget.model['param'];
textEditingController.text =
widget.model['param'];
}),
// initialValue: widget.model['param'],
autofocus: false,
@@ -232,7 +264,8 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
},
),
),
),
);
}),
].divide(SizedBox(width: 24.rpx)),
),
),
@@ -246,11 +279,16 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
child: Container(
width: 200.rpx,
child: TextFormField(
controller: repairController.onReDraw(
TextEditingController(text: widget.model['issue']),
(textEditingController) {
textEditingController.text = widget.model['issue'];
}),
onChanged: (value) {
widget.model['issue'] = value;
},
maxLines: null, // 👈 支持无限行
controller: TextEditingController(),
// controller: TextEditingController(),
autofocus: false,
obscureText: false,
decoration: InputDecoration(
@@ -385,7 +423,7 @@ class _RepairModelWidgetState extends State<RepairModelWidget> {
})),
),
),
if (widget.length > 1)
if (widget.length > 1 && widget.showDelete == true)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
100.rpx, 0.rpx, 100.rpx, 0.rpx),

View File

@@ -0,0 +1,285 @@
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/body_device_controller.dart';
import 'package:vbvs_app/controller/device/device_type_controller.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/pages/repair/component/RepairModelReadOnlyWidget.dart';
class RepairDetailPage extends StatefulWidget {
final dynamic data;
const RepairDetailPage({super.key, required this.data});
@override
State<RepairDetailPage> createState() => _RepairDetailPageState();
}
class _RepairDetailPageState extends State<RepairDetailPage> {
final ThemeController themeController = Get.find();
final DeviceTypeController deviceTypeController = Get.find();
final RepairController repairController = Get.find();
final BodyDeviceController bodyDeviceController = Get.find();
List<Map<String, dynamic>> devices = [];
final List<GlobalKey> repairItemKeys = [];
final GlobalKey contactKey = GlobalKey();
final GlobalKey phoneKey = GlobalKey();
late final TextEditingController _contactController;
late final TextEditingController _phoneController;
@override
void initState() {
super.initState();
devices = List<Map<String, dynamic>>.from(widget.data['device'] ?? []);
_updateRepairItemKeys();
_contactController = TextEditingController(
text: widget.data['contacts']?['name'] ?? '',
);
_phoneController = TextEditingController(
text: widget.data['contacts']?['phone'] ?? '',
);
}
void _updateRepairItemKeys() {
repairItemKeys
..clear()
..addAll(List.generate(devices.length, (_) => GlobalKey()));
}
@override
void dispose() {
_contactController.dispose();
_phoneController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodysize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'),
fit: BoxFit.fill,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(
color: themeController.currentColor.sc3,
),
titleSpacing: 0,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
Text(
'设备报修'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: themeController.currentColor.sc3,
letterSpacing: 0,
fontSize: 30.rpx,
),
),
Positioned(
left: 0,
// child: returnIconButtom,
child: returnIconButtomAddCallback(() {}),
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(30.rpx, 29.rpx, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
children: [
CustomCard(
borderRadius:
AppConstants().button_container_radius,
onTap: () {},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width: (MediaQuery.sizeOf(context).width * 0.284)
.rpx,
constraints: BoxConstraints(
minWidth: 213.rpx,
minHeight: 91.rpx,
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
"${widget.data['type']}",
style: TextStyle(
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
fontSize:
AppConstants().normal_text_fontSize,
),
),
),
),
),
],
),
/// 设备列表
Column(
children: List.generate(devices.length, (index) {
final item = devices[index];
return RepairModelReadOnlyWidget(
widgetKey: repairItemKeys[index],
model: item,
onTap: () {},
length: devices.length,
showDelete: false,
);
}).divide(SizedBox(height: 25.rpx)),
),
/// 联系方式区域
Container(
width: double.infinity,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 30.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
_buildParamRow(
context,
"联系人".tr,
"名称输入提示".tr,
(value) => repairController.name.value = value,
key: contactKey,
controller: _contactController,
),
_buildParamRow(
context,
"手机号".tr,
"手机号输入提示".tr,
(value) => repairController.phone.value = value,
key: phoneKey,
controller: _phoneController,
),
].divide(SizedBox(height: 30.rpx)),
),
),
),
]
.divide(SizedBox(height: 25.rpx))
.addToEnd(SizedBox(height: 25.rpx)),
),
),
),
),
),
),
),
);
}
Widget _buildParamRow(
BuildContext context,
String text,
String hinttext,
void Function(String)? onChanged, {
Key? key,
required TextEditingController controller,
}) {
return Row(
key: key,
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 110.rpx,
child: Text(
text,
style: TextStyle(
fontSize: 26.rpx,
letterSpacing: 0.0,
color: themeController.currentColor.sc3,
),
overflow: TextOverflow.ellipsis,
softWrap: false,
maxLines: 1,
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.rpx),
color: Colors.transparent,
),
child: TextFormField(
readOnly: true,
controller: controller,
autofocus: false,
decoration: InputDecoration(
isDense: true,
hintText: hinttext,
hintStyle: TextStyle(
letterSpacing: 0.0,
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc4,
),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent, width: 1.rpx),
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent, width: 1.rpx),
borderRadius: BorderRadius.circular(8.rpx),
),
filled: true,
fillColor: themeController.currentColor.sc15,
),
style: TextStyle(
letterSpacing: 0.0,
color: themeController.currentColor.sc4,
fontSize: AppConstants().normal_text_fontSize,
),
cursorColor: themeController.currentColor.sc3,
onChanged: onChanged,
),
),
),
].divide(SizedBox(width: 24.rpx)),
);
}
}

View File

@@ -1,8 +1,13 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/repair/component/RepairHistoryInfoWidget.dart';
class RepairListPage extends StatefulWidget {
@@ -13,6 +18,8 @@ class RepairListPage extends StatefulWidget {
}
class _RepairListPageState extends State<RepairListPage> {
RepairController repairController = Get.find();
@override
void initState() {
super.initState();
@@ -92,26 +99,23 @@ class _RepairListPageState extends State<RepairListPage> {
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(30.rpx, 29.rpx, 30.rpx, 0),
child: SingleChildScrollView(
child: Obx(() {
final isEmpty = repairController.repairHistory.value.isEmpty;
if (isEmpty) {
return Expanded(child: NullDataWidget());
}
return SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
RepairHistoryInfoWidget(),
]
.divide(SizedBox(
height: 25.rpx,
))
.addToEnd(SizedBox(
height: 25.rpx,
)),
),
children: repairController.repairHistory.value
.map((item) => RepairHistoryInfoWidget(
data: item)) // 假设组件支持传 data
.toList()
.divide(SizedBox(height: 25.rpx))
.addToEnd(SizedBox(height: 25.rpx)),
),
);
}),
),
),
),
@@ -121,11 +125,14 @@ class _RepairListPageState extends State<RepairListPage> {
}
Future<void> loadData() async {
// repairController.repairHistory.value = [{}];
// ApiResponse apiResponse = await requestWithLog(
// logTitle: "请求维修列表", method: MyHttpMethod.get, queryUrl: "");
// if (apiResponse.code == HttpStatusCodes.ok) {
// //请求维修列表
// }
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.submit_repair;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
ApiResponse apiResponse = await requestWithLog(
logTitle: "查询报修数据", method: MyHttpMethod.get, queryUrl: queryUrl);
RepairController repairController = Get.find();
repairController.repairHistory.value = apiResponse.data;
repairController.updateAll();
}
}

View File

@@ -1,7 +1,7 @@
import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/pages/device/BodyDeviceWidget.dart';
import 'package:vbvs_app/pages/device/device_detail.dart';
@@ -27,6 +27,8 @@ import 'package:vbvs_app/pages/main_bottom/mine_page.dart';
import 'package:vbvs_app/pages/person/person_page.dart';
import 'package:vbvs_app/pages/person/update_person_page.dart';
import 'package:vbvs_app/pages/repair/apply_repair_page.dart';
import 'package:vbvs_app/pages/repair/apply_repair_success.dart';
import 'package:vbvs_app/pages/repair/repair_detail_page.dart';
import 'package:vbvs_app/pages/repair/repair_list_page.dart';
import 'package:vbvs_app/pages/setting/language_setting.dart';
import 'package:vbvs_app/pages/sleep_report/new_sleep_report_page.dart';
@@ -37,8 +39,6 @@ import 'package:vbvs_app/pages/user/setting_page.dart';
import 'package:vbvs_app/pages/user/update_user_page.dart';
import 'package:vbvs_app/pages/user/user_scheme_page.dart';
ThemeController themeController = Get.find();
var routes = {
"/homePage": (contxt) => HomePage(),
"/sleepReportPage": (contxt, {arguments}) =>
@@ -79,6 +79,9 @@ var routes = {
NewSleepReportPage(date: arguments),
"/userSchemePage": (contxt) => UserSchemePage(),
"/privacyPage": (contxt) => PrivacySchemePage(),
"/repairDetailPage": (contxt, {arguments}) =>
RepairDetailPage(data: arguments),
"/applyRepairSuccess": (contxt) => ApplyRepairSuccess(),
};
var onGenerateRoute = (RouteSettings settings) {