You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
10 KiB
347 lines
10 KiB
import 'dart:ui';
|
|
|
|
import '/modules/devices/controllers/devices_controller.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import '/core/theme/app_colors.dart';
|
|
import '/data/models/user_Info.dart';
|
|
import '../controllers/devices_controller.dart';
|
|
|
|
// 设备类型枚举
|
|
enum DeviceType {
|
|
Unknown(0),
|
|
Classic_bluetooth_Headset(1),
|
|
BLE_Bluetooth_Headset(2),
|
|
Smart_Voice_Recorder(3),
|
|
SmartEye(4);
|
|
|
|
const DeviceType(this.value);
|
|
final int value;
|
|
|
|
// 使用getter获取多语言显示名称
|
|
String get displayName {
|
|
switch (this) {
|
|
case DeviceType.Unknown:
|
|
return "deviceTypeUnknown".tr;
|
|
case DeviceType.Classic_bluetooth_Headset:
|
|
return "deviceTypeClassicBluetoothHeadset".tr;
|
|
case DeviceType.BLE_Bluetooth_Headset:
|
|
return "deviceTypeBleBluetoothHeadset".tr;
|
|
case DeviceType.Smart_Voice_Recorder:
|
|
return "deviceTypeSmartVoiceRecorder".tr;
|
|
case DeviceType.SmartEye:
|
|
return "deviceTypeSmartEye".tr;
|
|
}
|
|
}
|
|
|
|
static DeviceType fromValue(int value) {
|
|
return DeviceType.values.firstWhere(
|
|
(type) => type.value == value,
|
|
orElse: () => DeviceType.Unknown,
|
|
);
|
|
}
|
|
|
|
IconData get icon {
|
|
switch (this) {
|
|
case DeviceType.Classic_bluetooth_Headset:
|
|
case DeviceType.BLE_Bluetooth_Headset:
|
|
return Icons.headphones;
|
|
case DeviceType.Smart_Voice_Recorder:
|
|
return Icons.mic;
|
|
case DeviceType.SmartEye:
|
|
return Icons.visibility;
|
|
default:
|
|
return Icons.device_unknown;
|
|
}
|
|
}
|
|
}
|
|
|
|
class DevicesView extends GetView<DevicesController> {
|
|
const DevicesView({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
|
|
|
return Scaffold(
|
|
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white,
|
|
body: Column(
|
|
children: [
|
|
// 顶部标题栏
|
|
Container(
|
|
padding: EdgeInsets.only(
|
|
top: MediaQuery.of(context).padding.top + 10.h,
|
|
left: 20.w,
|
|
right: 20.w,
|
|
bottom: 20.h,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: isDarkMode ? Colors.black : Colors.white,
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Row(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: () => Get.back(),
|
|
child: Icon(
|
|
Icons.arrow_back_ios,
|
|
color: isDarkMode ? Colors.white : Colors.black,
|
|
size: 24.sp,
|
|
),
|
|
),
|
|
SizedBox(width: 16.w),
|
|
Text(
|
|
"deviceManagement".tr,
|
|
style: TextStyle(
|
|
fontSize: 20.sp,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDarkMode ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// 设备列表内容
|
|
Expanded(
|
|
child: _buildDevicesList(isDarkMode),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDevicesList(bool isDarkMode) {
|
|
return Obx(() {
|
|
// 使用控制器的响应式数据,这会触发控制器的实例化
|
|
final groupedDevices = controller.devices;
|
|
|
|
if (groupedDevices.isEmpty) {
|
|
return _buildEmptyState(isDarkMode);
|
|
}
|
|
|
|
return ListView(
|
|
padding: EdgeInsets.all(20.w),
|
|
children: [
|
|
// 遍历每个设备类型
|
|
...groupedDevices.entries.map((entry) {
|
|
final deviceTypeValue = entry.key;
|
|
final deviceList = entry.value;
|
|
final deviceType = DeviceType.fromValue(deviceTypeValue);
|
|
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// 设备类型标题
|
|
Padding(
|
|
padding: EdgeInsets.only(bottom: 12.h),
|
|
child: Text(
|
|
deviceType.displayName,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDarkMode ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
),
|
|
// 该类型下的设备列表
|
|
...deviceList.map((device) => _buildDeviceCard(
|
|
device: device,
|
|
deviceType: deviceType,
|
|
isDarkMode: isDarkMode,
|
|
)),
|
|
SizedBox(height: 20.h),
|
|
],
|
|
);
|
|
}).toList(),
|
|
],
|
|
);
|
|
});
|
|
}
|
|
|
|
Widget _buildEmptyState(bool isDarkMode) {
|
|
return Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
Icons.devices_other,
|
|
size: 80.sp,
|
|
color: isDarkMode ? Colors.white54 : Colors.grey[400],
|
|
),
|
|
SizedBox(height: 20.h),
|
|
Text(
|
|
"noDevicesBound".tr,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
color: isDarkMode ? Colors.white70 : Colors.grey[600],
|
|
),
|
|
),
|
|
SizedBox(height: 12.h),
|
|
Text(
|
|
"pleaseBindDeviceFirst".tr,
|
|
style: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: isDarkMode ? Colors.white54 : Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDeviceCard({
|
|
required UserDevice device,
|
|
required DeviceType deviceType,
|
|
required bool isDarkMode,
|
|
}) {
|
|
return Container(
|
|
margin: EdgeInsets.only(bottom: 12.h),
|
|
padding: EdgeInsets.all(16.w),
|
|
decoration: BoxDecoration(
|
|
color: isDarkMode ? AppColors.cardBackground : Colors.white,
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.05),
|
|
blurRadius: 8,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// 设备图标
|
|
Container(
|
|
width: 48.w,
|
|
height: 48.w,
|
|
decoration: BoxDecoration(
|
|
color:
|
|
isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[100],
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
),
|
|
child: Icon(
|
|
deviceType.icon,
|
|
color: isDarkMode ? Colors.white : Colors.black87,
|
|
size: 24.sp,
|
|
),
|
|
),
|
|
SizedBox(width: 16.w),
|
|
// 设备信息
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
device.devicename.isNotEmpty
|
|
? device.devicename
|
|
: "deviceTypeUnknown".tr,
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDarkMode ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
SizedBox(height: 4.h),
|
|
Text(
|
|
device.devicemac.isNotEmpty
|
|
? device.devicemac
|
|
: "noMacAddress".tr,
|
|
style: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: isDarkMode ? Colors.white70 : Colors.grey[600],
|
|
),
|
|
),
|
|
if (device.license.isNotEmpty) ...[
|
|
SizedBox(height: 4.h),
|
|
Text(
|
|
"${"licenseCode".tr}: ${device.license}",
|
|
style: TextStyle(
|
|
fontSize: 12.sp,
|
|
color: isDarkMode ? Colors.white54 : Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
// 解绑按钮
|
|
GestureDetector(
|
|
onTap: () => _showUnbindDialog(device, isDarkMode),
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: 12.w,
|
|
vertical: 6.h,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Colors.red.withOpacity(0.1),
|
|
borderRadius: BorderRadius.circular(6.r),
|
|
border: Border.all(
|
|
color: Colors.red.withOpacity(0.3),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Text(
|
|
"unbind".tr,
|
|
style: TextStyle(
|
|
fontSize: 12.sp,
|
|
color: Colors.red,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _showUnbindDialog(UserDevice device, bool isDarkMode) {
|
|
Get.dialog(
|
|
AlertDialog(
|
|
backgroundColor: isDarkMode ? AppColors.cardBackground : Colors.white,
|
|
title: Text(
|
|
"confirmUnbind".tr,
|
|
style: TextStyle(
|
|
color: isDarkMode ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
content: Text(
|
|
"confirmUnbindMessage"
|
|
.tr
|
|
.replaceAll('{deviceName}', device.devicename),
|
|
style: TextStyle(
|
|
color: isDarkMode ? Colors.white70 : Colors.black54,
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Get.back(),
|
|
child: Text(
|
|
"cancel".tr,
|
|
style: TextStyle(
|
|
color: isDarkMode ? Colors.white70 : Colors.grey[600],
|
|
),
|
|
),
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
Get.back();
|
|
controller.unbindearphone(device);
|
|
},
|
|
child: Text(
|
|
"confirmUnbindAction".tr,
|
|
style: const TextStyle(color: Colors.red),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|